diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
index eed86fa971f..3e349deba89 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
@@ -159,7 +159,7 @@ nsTableCellFrame::GetSkipSides() const
* Align the cell's child frame within the cell
*
*/
-void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
+void nsTableCellFrame::VerticallyAlignChild()
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
@@ -174,12 +174,10 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
if (textStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) {
verticalAlignFlags = textStyle->mVerticalAlign.GetIntValue();
}
-
- nscoord height = mRect.height;
-
- nsRect kidRect;
+ nscoord height = mRect.height;
+ nsRect kidRect;
mFirstChild->GetRect(kidRect);
- nscoord childHeight = kidRect.height;
+ nscoord childHeight = kidRect.height;
// Vertically align the child
@@ -618,8 +616,7 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
nsTableFrame* tableFrame;
nsTableFrame::GetTableFrame(this, tableFrame);
- //tableFrame->GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
- NS_ASSERTION(tableFrame,"Table Must not be null");
+ NS_ASSERTION(tableFrame,"Table must not be null");
if (!tableFrame)
return;
@@ -654,6 +651,8 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
border = NSIntPixelsToTwips(1, p2t);
MapHTMLBorderStyle(aPresContext, *spacingData, border, tableFrame);
}
+
+ // TODO: map the align attributes here
}
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.h b/mozilla/layout/html/table/src/nsTableCellFrame.h
index 80f92b684a2..aa3bca8ce78 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.h
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.h
@@ -76,7 +76,7 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
- void VerticallyAlignChild(nsIPresContext* aPresContext);
+ virtual void VerticallyAlignChild();
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index a733033806e..c1f4b883796 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -389,7 +389,7 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
return mColCount;
}
-PRInt32 nsTableFrame::GetRowCount ()
+PRInt32 nsTableFrame::GetRowCount () const
{
PRInt32 rowCount = 0;
nsCellMap *cellMap = GetCellMap();
@@ -1750,7 +1750,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
// Return our size and our status
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
- aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom;
+ nscoord defaultHeight = state.y + myBorderPadding.top + myBorderPadding.bottom;
+ aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
@@ -2764,6 +2765,151 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext)
SetRect(tableSize);
}
+/* get the height of this table's container. ignore all containers who have unconstrained height.
+ * take into account the possibility that this table is nested.
+ * if nested within an auto-height table, this method returns 0.
+ * this method may also return NS_UNCONSTRAINEDSIZE, meaning no container provided any height constraint
+ */
+nscoord nsTableFrame::GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState)
+{
+ nscoord result=-1;
+ const nsHTMLReflowState* rs = &aReflowState;
+ while (nsnull!=rs)
+ {
+ const nsStyleDisplay *display;
+ rs->frame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE==display->mDisplay)
+ {
+ const nsStylePosition *position;
+ rs->frame->GetStyleData(eStyleStruct_Position, (nsStyleStruct *&)position);
+ nsStyleUnit unit = position->mHeight.GetUnit();
+ if (eStyleUnit_Null==unit || eStyleUnit_Auto==unit)
+ {
+ result = 0;
+ break;
+ }
+ }
+ if (eHTMLFrameConstraint_Fixed==rs->heightConstraint ||
+ eHTMLFrameConstraint_FixedContent==rs->heightConstraint)
+ {
+ result = rs->maxSize.height;
+ break;
+ }
+ // XXX: evil cast!
+ rs = (nsHTMLReflowState *)(rs->parentReflowState);
+ }
+ NS_ASSERTION(-1!=result, "bad state: no constrained height in reflow chain");
+ return result;
+}
+
+/**
+ get the table height attribute
+ if it is auto, table height = SUM(height of rowgroups)
+ else if (resolved table height attribute > SUM(height of rowgroups))
+ proportionately distribute extra height to each row
+ we assume we are passed in the default table height==the sum of the heights of the table's rowgroups
+ in aDesiredSize.height.
+ */
+nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState,
+ nscoord aDefaultHeight)
+{
+ NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
+ NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
+ nsresult rv = NS_OK;
+ nscoord result = aDefaultHeight;
+ const nsStylePosition* tablePosition;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)tablePosition);
+ if (eStyleUnit_Auto == tablePosition->mHeight.GetUnit())
+ return result; // auto width tables are sized by the row heights, which we already have
+
+ nscoord tableSpecifiedHeight=-1;
+ if (eStyleUnit_Coord == tablePosition->mHeight.GetUnit())
+ tableSpecifiedHeight = tablePosition->mHeight.GetCoordValue();
+ else if (eStyleUnit_Percent == tablePosition->mHeight.GetUnit())
+ {
+ float percent = tablePosition->mHeight.GetPercentValue();
+ nscoord parentHeight = GetEffectiveContainerHeight(aReflowState);
+ if (NS_UNCONSTRAINEDSIZE!=parentHeight && 0!=parentHeight)
+ tableSpecifiedHeight = NSToCoordRound((float)parentHeight * percent);
+ }
+ if (-1!=tableSpecifiedHeight)
+ {
+ if (tableSpecifiedHeight>aDefaultHeight)
+ { // proportionately distribute the excess height to each row
+ result = tableSpecifiedHeight;
+ nscoord excess = tableSpecifiedHeight-aDefaultHeight;
+ nscoord sumOfRowHeights=0;
+ nsIFrame * rowGroupFrame=mFirstChild;
+ while (nsnull!=rowGroupFrame)
+ {
+ const nsStyleDisplay *rowGroupDisplay;
+ rowGroupFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowGroupDisplay));
+ if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
+ { // the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
+ // and the rowgroup itself needs to be expanded by SUM(row height deltas)
+ nscoord excessForRowGroup=0;
+ nsIFrame * rowFrame=nsnull;
+ rv = rowGroupFrame->FirstChild(nsnull, rowFrame);
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
+ { // the row needs to be expanded by the proportion this row contributed to the original height
+ nsRect rowRect;
+ rowFrame->GetRect(rowRect);
+ sumOfRowHeights += rowRect.height;
+ }
+ rowFrame->GetNextSibling(rowFrame);
+ }
+ }
+ rowGroupFrame->GetNextSibling(rowGroupFrame);
+ }
+ rowGroupFrame=mFirstChild;
+ nscoord y=0;
+ while (nsnull!=rowGroupFrame)
+ {
+ const nsStyleDisplay *rowGroupDisplay;
+ rowGroupFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowGroupDisplay));
+ if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
+ { // the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
+ // and the rowgroup itself needs to be expanded by SUM(row height deltas)
+ nscoord excessForRowGroup=0;
+ nsIFrame * rowFrame=nsnull;
+ rv = rowGroupFrame->FirstChild(nsnull, rowFrame);
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
+ { // the row needs to be expanded by the proportion this row contributed to the original height
+ nsRect rowRect;
+ rowFrame->GetRect(rowRect);
+ float percent = ((float)(rowRect.height)) / ((float)(sumOfRowHeights));
+ nscoord excessForRow = NSToCoordRound((float)excess*percent);
+ nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow+rowRect.height);
+ rowFrame->SetRect(newRowRect);
+ // resize cells, too
+ ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
+ // better if this were part of an overloaded row::SetRect
+ y += excessForRow+rowRect.height;
+ excessForRowGroup += excessForRow;
+ }
+ rowFrame->GetNextSibling(rowFrame);
+ }
+ nsRect rowGroupRect;
+ rowGroupFrame->GetRect(rowGroupRect);
+ nsRect newRowGroupRect(rowGroupRect.x, rowGroupRect.y, rowGroupRect.width, excessForRowGroup+rowGroupRect.height);
+ rowGroupFrame->SetRect(newRowGroupRect);
+ }
+ rowGroupFrame->GetNextSibling(rowGroupFrame);
+ }
+ }
+ }
+ return result;
+}
+
void nsTableFrame::AdjustColumnsForCOLSAttribute()
{
nsCellMap *cellMap = GetCellMap();
@@ -2979,7 +3125,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
mColCache = new ColumnInfoCache(GetColCount());
nsIFrame * childFrame = mFirstChild;
while (nsnull!=childFrame)
- { // in this loop, we cache column info and set column style info from cells in first row
+ { // in this loop, we cache column info and set column style info from cells
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
@@ -3038,7 +3184,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
}
// second time through, set column cache info for each column
- // we can't do this until the loop above has set the column style info from the cells in the first row
+ // we can't do this until the loop above has set the column style info from the cells
childFrame = mFirstChild;
while (nsnull!=childFrame)
{ // for every child, if it's a col group then get the columns
@@ -3512,9 +3658,7 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
// Walk up the reflow state chain until we find a block
// frame. Our width is computed relative to there.
const nsReflowState* rs = &aReflowState;
- nsIFrame *childFrame=nsnull;
- nsIFrame *grandchildFrame=nsnull;
- nsIFrame *greatgrandchildFrame=nsnull;
+ nsTableCellFrame *lastCellFrame=nsnull;
while (nsnull != rs)
{
// if it's a block, use its max width
@@ -3560,17 +3704,18 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
if (NS_STYLE_DISPLAY_TABLE_CELL==display->mDisplay)
{ // if it's a cell and the cell has a specified width, use it
// Compute and subtract out the insets (sum of border and padding) for the table
+ lastCellFrame = (nsTableCellFrame*)(rs->frame);
const nsStylePosition* cellPosition;
- rs->frame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)cellPosition));
+ lastCellFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)cellPosition));
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nsTableFrame *tableParent;
- nsresult rv=GetTableFrame(rs->frame, tableParent);
+ nsresult rv=GetTableFrame(lastCellFrame, tableParent);
if ((NS_OK==rv) && (nsnull!=tableParent) && (nsnull!=tableParent->mColumnWidths))
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame *)rs->frame)->GetColIndex();
- PRInt32 colSpan = tableParent->GetEffectiveColSpan(colIndex, (nsTableCellFrame *)rs->frame);
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = tableParent->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i=0; iGetColumnWidth(colIndex);
break;
@@ -3581,12 +3726,12 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
{
parentWidth = cellPosition->mWidth.GetCoordValue();
// subtract out cell border and padding
- rs->frame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (PR_TRUE==gsDebugNT)
printf("%p: found a cell frame %p with fixed coord width %d, returning parentWidth %d\n",
- aReflowState.frame, rs->frame, cellPosition->mWidth.GetCoordValue(), parentWidth);
+ aReflowState.frame, lastCellFrame, cellPosition->mWidth.GetCoordValue(), parentWidth);
break;
}
}
@@ -3618,16 +3763,16 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
if (eStyleUnit_Auto == tablePosition->mWidth.GetUnit())
{
parentWidth = NS_UNCONSTRAINEDSIZE;
- if (nsnull != ((nsTableFrame*)rs->frame)->mColumnWidths)
+ if (nsnull != ((nsTableFrame*)(rs->frame))->mColumnWidths)
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame *)greatgrandchildFrame)->GetColIndex();
- PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = ((nsTableFrame*)(rs->frame))->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i = 0; iframe)->GetColumnWidth(i+colIndex);
+ parentWidth += ((nsTableFrame*)(rs->frame))->GetColumnWidth(i+colIndex);
// subtract out cell border and padding
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (PR_TRUE==gsDebugNT)
printf("%p: found a table frame %p with auto width, returning parentWidth %d from cell in col %d with span %d\n",
@@ -3642,13 +3787,13 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
}
else
{
- if (nsnull!=((nsTableFrame*)rs->frame)->mColumnWidths)
+ if (nsnull!=((nsTableFrame*)(rs->frame))->mColumnWidths)
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
- PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = ((nsTableFrame*)(rs->frame))->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i = 0; iframe)->GetColumnWidth(i+colIndex);
+ parentWidth += ((nsTableFrame*)(rs->frame))->GetColumnWidth(i+colIndex);
}
else
{
@@ -3659,17 +3804,9 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
{ // the table has been sized, so we can compute the available space for the child
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row group
- childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(childFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row
- grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the cell
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ // factor in the cell
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
}
else
@@ -3693,19 +3830,6 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
}
}
- if (nsnull==childFrame)
- childFrame = rs->frame;
- else if (nsnull==grandchildFrame)
- {
- grandchildFrame = childFrame;
- childFrame = rs->frame;
- }
- else
- {
- greatgrandchildFrame = grandchildFrame;
- grandchildFrame = childFrame;
- childFrame = rs->frame;
- }
rs = rs->parentReflowState;
}
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index 716664e3c18..97ef0dc38fc 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -90,7 +90,7 @@ public:
/** return PR_TRUE if aDisplayType represents a rowgroup of any sort
* (header, footer, or body)
*/
- PRBool IsRowGroup(PRInt32 aDisplayType);
+ PRBool IsRowGroup(PRInt32 aDisplayType) const;
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
@@ -368,6 +368,12 @@ protected:
*/
nscoord ComputeDesiredWidth(const nsHTMLReflowState& aReflowState) const;
+ nscoord ComputeDesiredHeight(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState,
+ nscoord aDefaultHeight);
+
+ nscoord GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState);
+
nscoord GetTopMarginFor(nsIPresContext& aCX,
InnerTableReflowState& aReflowState,
const nsMargin& aKidMargin);
@@ -524,7 +530,7 @@ public: /* ----- Cell Map public methods ----- */
* if mCellMap has been created, it is asked for the number of rows.
* otherwise, the content is enumerated and the rows are counted.
*/
- virtual PRInt32 GetRowCount();
+ virtual PRInt32 GetRowCount() const;
/** returns the number of columns in this table. */
virtual PRInt32 GetColCount();
@@ -605,7 +611,7 @@ private:
};
-inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType)
+inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
{
return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index 7929a818c98..2aca5b9f45c 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -174,55 +174,61 @@ nsTableRowFrame::InitChildren(PRInt32 aRowIndex)
/**
* Post-reflow hook. This is where the table row does its post-processing
*/
-NS_METHOD
-nsTableRowFrame::DidReflow(nsIPresContext& aPresContext,
- nsDidReflowStatus aStatus)
+void
+nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState)
{
- if (gsDebug) printf("Row %p DidReflow: begin mRect.h=%d, mCellMTM=%d, mCellMBM=%d\n",
+ if (gsDebug) printf("Row %p DidResize: begin mRect.h=%d, mCellMTM=%d, mCellMBM=%d\n",
this, mRect.height, mCellMaxTopMargin, mCellMaxBottomMargin);
- if (NS_FRAME_REFLOW_FINISHED == aStatus) {
- // Resize and re-align the cell frames based on our row height
- nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
- if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
- nsIFrame *cellFrame = mFirstChild;
- nsTableFrame* tableFrame;
- nsTableFrame::GetTableFrame(this, tableFrame);
- while (nsnull != cellFrame)
+ // Resize and re-align the cell frames based on our row height
+ nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
+ if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
+ nsIFrame *cellFrame = mFirstChild;
+ nsTableFrame* tableFrame;
+ nsTableFrame::GetTableFrame(this, tableFrame);
+ while (nsnull != cellFrame)
+ {
+ const nsStyleDisplay *kidDisplay;
+ cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
- const nsStyleDisplay *kidDisplay;
- cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, (nsTableCellFrame *)cellFrame);
+ if (gsDebug) printf("Row DidReflow: cellFrame %p ", cellFrame);
+ if (1==rowSpan)
{
- PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, (nsTableCellFrame *)cellFrame);
- if (gsDebug) printf("Row DidReflow: cellFrame %p ", cellFrame);
- if (1==rowSpan)
+ // resize the cell's height
+ nsSize cellFrameSize;
+ cellFrame->GetSize(cellFrameSize);
+ if (cellFrameSize.height!=cellHeight)
{
- // resize the cell's height
- nsSize cellFrameSize;
- cellFrame->GetSize(cellFrameSize);
cellFrame->SizeTo(cellFrameSize.width, cellHeight);
if (gsDebug) printf("given height %d\n", cellHeight);
// realign cell content based on the new height
- ((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(&aPresContext);
- }
- else
- {
- if (gsDebug)
- {
- nsSize cellFrameSize;
- cellFrame->GetSize(cellFrameSize);
- printf("has rowspan %d and height %d, unchanged.\n", rowSpan, cellFrameSize.height);
- }
+ nsHTMLReflowMetrics desiredSize(nsnull);
+ nsHTMLReflowState kidReflowState(aPresContext, cellFrame,
+ aReflowState, nsSize(cellFrameSize.width, cellHeight),
+ eReflowReason_Resize);
+ nsReflowStatus status;
+ ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status);
+ ((nsTableCellFrame *)cellFrame)->VerticallyAlignChild();
+ }
+ }
+ else
+ {
+ if (gsDebug)
+ {
+ nsSize cellFrameSize;
+ cellFrame->GetSize(cellFrameSize);
+ printf("has rowspan %d and height %d, unchanged.\n", rowSpan, cellFrameSize.height);
}
}
- // Get the next cell
- cellFrame->GetNextSibling(cellFrame);
}
+ // Get the next cell
+ cellFrame->GetNextSibling(cellFrame);
}
// Let our base class do the usual work
- if (gsDebug) printf("Row DidReflow: returning superclass DidReflow.\n");
- return nsContainerFrame::DidReflow(aPresContext, aStatus);
+ if (gsDebug) printf("Row DidResize: returning NS_OK.\n");
}
void nsTableRowFrame::ResetMaxChildHeight()
@@ -449,6 +455,22 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
}
}
+nsIFrame * nsTableRowFrame::GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild)
+{
+ NS_ASSERTION(nsnull!=aCurrentChild, "bad arg");
+
+ nsIFrame *result=nsnull;
+ aCurrentChild->GetNextSibling(result);
+ return result;
+}
+
+nsIFrame * nsTableRowFrame::GetFirstChildForDirection(PRUint8 aDir)
+{
+ nsIFrame *result=nsnull;
+ result = mFirstChild;
+ return result;
+}
+
/**
* Called for a resize reflow. Typically because the column widths have
* changed. Reflows all the existing table cell frames
@@ -461,18 +483,22 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
if (nsnull == mFirstChild)
return NS_OK;
- nsresult rv=NS_OK;
- nsSize kidMaxElementSize;
- PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
- nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
- &kidMaxElementSize : nsnull;
- nscoord maxCellTopMargin = 0;
- nscoord maxCellBottomMargin = 0;
+ nsresult rv=NS_OK;
+ nsSize kidMaxElementSize;
+ PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
+ nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
+ &kidMaxElementSize : nsnull;
+ nscoord maxCellTopMargin = 0;
+ nscoord maxCellBottomMargin = 0;
nscoord cellSpacing = aReflowState.tableFrame->GetCellSpacing();
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
if (PR_TRUE==gsDebug) printf("Row %p: Resize Reflow\n", this);
+
// Reflow each of our existing cell frames
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
+ const nsStyleDisplay *rowDisplay;
+ GetStyleData(eStyleStruct_Display, (nsStyleStruct*&)rowDisplay);
+ nsIFrame* kidFrame=GetFirstChildForDirection(rowDisplay->mDirection);
+ for (kidFrame; nsnull != kidFrame; )
{
const nsStyleDisplay *kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
@@ -621,7 +647,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
}
// Get the next child
- kidFrame->GetNextSibling(kidFrame);
+ kidFrame = GetNextChildForDirection(rowDisplay->mDirection, kidFrame);
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
if ((nsnull==kidFrame) && (cellColSpan>1))
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h
index 9625fa66992..65d6d169818 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.h
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.h
@@ -93,8 +93,8 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
- NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
- nsDidReflowStatus aStatus);
+ virtual void DidResize(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState);
/** @see nsContainerFrame::CreateContinuingFrame */
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
@@ -214,6 +214,9 @@ protected:
nscoord ComputeCellAvailWidth(const RowReflowState& aState,
nsIFrame* aKidFrame) const;
+ nsIFrame * GetFirstChildForDirection(PRUint8 aDir);
+ nsIFrame * GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild);
+
/**
* Called for a resize reflow. Typically because the column widths have
* changed. Reflows all the existing table cell frames
diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
index be496ce96e2..8bae925ef96 100644
--- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
@@ -601,12 +601,15 @@ NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext
return rv;
}
-/**
- */
-void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize)
+/* CalculateRowHeights provides default heights for all rows in the rowgroup.
+ * Actual row heights are ultimately determined by the table, when the table
+ * height attribute is factored in.
+ */
+void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState)
{
- if (gsDebug) printf("TRGF ShrinkWrapChildren begin\n");
+ if (gsDebug) printf("TRGF CalculateRowHeights begin\n");
// iterate children and for each row get its height
PRBool atLeastOneRowSpanningCell = PR_FALSE;
nscoord topInnerMargin = 0;
@@ -717,7 +720,7 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
cellFrameSize.height, heightOfRowsSpanned);
cellFrame->SizeTo(cellFrameSize.width, heightOfRowsSpanned);
// Realign cell content based on new height
- ((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
+ ((nsTableCellFrame*)cellFrame)->VerticallyAlignChild();
}
/* otherwise, distribute the excess height to the rows effected.
* push all subsequent rows down by the total change in height of all the rows above it
@@ -781,6 +784,20 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
}
}
+ // finally, notify the rows of their new heights
+ rowFrame = mFirstChild;
+ while (nsnull != rowFrame)
+ {
+ const nsStyleDisplay *childDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
+ {
+ ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
+ }
+ // Get the next row
+ rowFrame->GetNextSibling(rowFrame);
+ }
+
// Adjust our desired size
aDesiredSize.height = rowGroupHeight;
@@ -907,7 +924,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height = state.y;
// shrink wrap rows to height of tallest cell in that row
- ShrinkWrapChildren(&aPresContext, aDesiredSize);
+ if (eReflowReason_Initial != aReflowState.reason) {
+ CalculateRowHeights(aPresContext, aDesiredSize, aReflowState);
+ }
}
if (gsDebug==PR_TRUE)
@@ -1337,3 +1356,4 @@ nsTableRowGroupFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TableRowGroup", aResult);
}
+
diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
index c2bfd335b03..12bbfbb8dfd 100644
--- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
+++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
@@ -133,8 +133,9 @@ protected:
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
- void ShrinkWrapChildren(nsIPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize);
+ void CalculateRowHeights(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState);
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp
index eed86fa971f..3e349deba89 100644
--- a/mozilla/layout/tables/nsTableCellFrame.cpp
+++ b/mozilla/layout/tables/nsTableCellFrame.cpp
@@ -159,7 +159,7 @@ nsTableCellFrame::GetSkipSides() const
* Align the cell's child frame within the cell
*
*/
-void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
+void nsTableCellFrame::VerticallyAlignChild()
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
@@ -174,12 +174,10 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
if (textStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) {
verticalAlignFlags = textStyle->mVerticalAlign.GetIntValue();
}
-
- nscoord height = mRect.height;
-
- nsRect kidRect;
+ nscoord height = mRect.height;
+ nsRect kidRect;
mFirstChild->GetRect(kidRect);
- nscoord childHeight = kidRect.height;
+ nscoord childHeight = kidRect.height;
// Vertically align the child
@@ -618,8 +616,7 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
nsTableFrame* tableFrame;
nsTableFrame::GetTableFrame(this, tableFrame);
- //tableFrame->GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
- NS_ASSERTION(tableFrame,"Table Must not be null");
+ NS_ASSERTION(tableFrame,"Table must not be null");
if (!tableFrame)
return;
@@ -654,6 +651,8 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
border = NSIntPixelsToTwips(1, p2t);
MapHTMLBorderStyle(aPresContext, *spacingData, border, tableFrame);
}
+
+ // TODO: map the align attributes here
}
diff --git a/mozilla/layout/tables/nsTableCellFrame.h b/mozilla/layout/tables/nsTableCellFrame.h
index 80f92b684a2..aa3bca8ce78 100644
--- a/mozilla/layout/tables/nsTableCellFrame.h
+++ b/mozilla/layout/tables/nsTableCellFrame.h
@@ -76,7 +76,7 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
- void VerticallyAlignChild(nsIPresContext* aPresContext);
+ virtual void VerticallyAlignChild();
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index a733033806e..c1f4b883796 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -389,7 +389,7 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
return mColCount;
}
-PRInt32 nsTableFrame::GetRowCount ()
+PRInt32 nsTableFrame::GetRowCount () const
{
PRInt32 rowCount = 0;
nsCellMap *cellMap = GetCellMap();
@@ -1750,7 +1750,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
// Return our size and our status
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
- aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom;
+ nscoord defaultHeight = state.y + myBorderPadding.top + myBorderPadding.bottom;
+ aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
@@ -2764,6 +2765,151 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext)
SetRect(tableSize);
}
+/* get the height of this table's container. ignore all containers who have unconstrained height.
+ * take into account the possibility that this table is nested.
+ * if nested within an auto-height table, this method returns 0.
+ * this method may also return NS_UNCONSTRAINEDSIZE, meaning no container provided any height constraint
+ */
+nscoord nsTableFrame::GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState)
+{
+ nscoord result=-1;
+ const nsHTMLReflowState* rs = &aReflowState;
+ while (nsnull!=rs)
+ {
+ const nsStyleDisplay *display;
+ rs->frame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE==display->mDisplay)
+ {
+ const nsStylePosition *position;
+ rs->frame->GetStyleData(eStyleStruct_Position, (nsStyleStruct *&)position);
+ nsStyleUnit unit = position->mHeight.GetUnit();
+ if (eStyleUnit_Null==unit || eStyleUnit_Auto==unit)
+ {
+ result = 0;
+ break;
+ }
+ }
+ if (eHTMLFrameConstraint_Fixed==rs->heightConstraint ||
+ eHTMLFrameConstraint_FixedContent==rs->heightConstraint)
+ {
+ result = rs->maxSize.height;
+ break;
+ }
+ // XXX: evil cast!
+ rs = (nsHTMLReflowState *)(rs->parentReflowState);
+ }
+ NS_ASSERTION(-1!=result, "bad state: no constrained height in reflow chain");
+ return result;
+}
+
+/**
+ get the table height attribute
+ if it is auto, table height = SUM(height of rowgroups)
+ else if (resolved table height attribute > SUM(height of rowgroups))
+ proportionately distribute extra height to each row
+ we assume we are passed in the default table height==the sum of the heights of the table's rowgroups
+ in aDesiredSize.height.
+ */
+nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState,
+ nscoord aDefaultHeight)
+{
+ NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
+ NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
+ nsresult rv = NS_OK;
+ nscoord result = aDefaultHeight;
+ const nsStylePosition* tablePosition;
+ GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)tablePosition);
+ if (eStyleUnit_Auto == tablePosition->mHeight.GetUnit())
+ return result; // auto width tables are sized by the row heights, which we already have
+
+ nscoord tableSpecifiedHeight=-1;
+ if (eStyleUnit_Coord == tablePosition->mHeight.GetUnit())
+ tableSpecifiedHeight = tablePosition->mHeight.GetCoordValue();
+ else if (eStyleUnit_Percent == tablePosition->mHeight.GetUnit())
+ {
+ float percent = tablePosition->mHeight.GetPercentValue();
+ nscoord parentHeight = GetEffectiveContainerHeight(aReflowState);
+ if (NS_UNCONSTRAINEDSIZE!=parentHeight && 0!=parentHeight)
+ tableSpecifiedHeight = NSToCoordRound((float)parentHeight * percent);
+ }
+ if (-1!=tableSpecifiedHeight)
+ {
+ if (tableSpecifiedHeight>aDefaultHeight)
+ { // proportionately distribute the excess height to each row
+ result = tableSpecifiedHeight;
+ nscoord excess = tableSpecifiedHeight-aDefaultHeight;
+ nscoord sumOfRowHeights=0;
+ nsIFrame * rowGroupFrame=mFirstChild;
+ while (nsnull!=rowGroupFrame)
+ {
+ const nsStyleDisplay *rowGroupDisplay;
+ rowGroupFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowGroupDisplay));
+ if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
+ { // the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
+ // and the rowgroup itself needs to be expanded by SUM(row height deltas)
+ nscoord excessForRowGroup=0;
+ nsIFrame * rowFrame=nsnull;
+ rv = rowGroupFrame->FirstChild(nsnull, rowFrame);
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
+ { // the row needs to be expanded by the proportion this row contributed to the original height
+ nsRect rowRect;
+ rowFrame->GetRect(rowRect);
+ sumOfRowHeights += rowRect.height;
+ }
+ rowFrame->GetNextSibling(rowFrame);
+ }
+ }
+ rowGroupFrame->GetNextSibling(rowGroupFrame);
+ }
+ rowGroupFrame=mFirstChild;
+ nscoord y=0;
+ while (nsnull!=rowGroupFrame)
+ {
+ const nsStyleDisplay *rowGroupDisplay;
+ rowGroupFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowGroupDisplay));
+ if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
+ { // the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
+ // and the rowgroup itself needs to be expanded by SUM(row height deltas)
+ nscoord excessForRowGroup=0;
+ nsIFrame * rowFrame=nsnull;
+ rv = rowGroupFrame->FirstChild(nsnull, rowFrame);
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
+ { // the row needs to be expanded by the proportion this row contributed to the original height
+ nsRect rowRect;
+ rowFrame->GetRect(rowRect);
+ float percent = ((float)(rowRect.height)) / ((float)(sumOfRowHeights));
+ nscoord excessForRow = NSToCoordRound((float)excess*percent);
+ nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow+rowRect.height);
+ rowFrame->SetRect(newRowRect);
+ // resize cells, too
+ ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
+ // better if this were part of an overloaded row::SetRect
+ y += excessForRow+rowRect.height;
+ excessForRowGroup += excessForRow;
+ }
+ rowFrame->GetNextSibling(rowFrame);
+ }
+ nsRect rowGroupRect;
+ rowGroupFrame->GetRect(rowGroupRect);
+ nsRect newRowGroupRect(rowGroupRect.x, rowGroupRect.y, rowGroupRect.width, excessForRowGroup+rowGroupRect.height);
+ rowGroupFrame->SetRect(newRowGroupRect);
+ }
+ rowGroupFrame->GetNextSibling(rowGroupFrame);
+ }
+ }
+ }
+ return result;
+}
+
void nsTableFrame::AdjustColumnsForCOLSAttribute()
{
nsCellMap *cellMap = GetCellMap();
@@ -2979,7 +3125,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
mColCache = new ColumnInfoCache(GetColCount());
nsIFrame * childFrame = mFirstChild;
while (nsnull!=childFrame)
- { // in this loop, we cache column info and set column style info from cells in first row
+ { // in this loop, we cache column info and set column style info from cells
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
@@ -3038,7 +3184,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
}
// second time through, set column cache info for each column
- // we can't do this until the loop above has set the column style info from the cells in the first row
+ // we can't do this until the loop above has set the column style info from the cells
childFrame = mFirstChild;
while (nsnull!=childFrame)
{ // for every child, if it's a col group then get the columns
@@ -3512,9 +3658,7 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
// Walk up the reflow state chain until we find a block
// frame. Our width is computed relative to there.
const nsReflowState* rs = &aReflowState;
- nsIFrame *childFrame=nsnull;
- nsIFrame *grandchildFrame=nsnull;
- nsIFrame *greatgrandchildFrame=nsnull;
+ nsTableCellFrame *lastCellFrame=nsnull;
while (nsnull != rs)
{
// if it's a block, use its max width
@@ -3560,17 +3704,18 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
if (NS_STYLE_DISPLAY_TABLE_CELL==display->mDisplay)
{ // if it's a cell and the cell has a specified width, use it
// Compute and subtract out the insets (sum of border and padding) for the table
+ lastCellFrame = (nsTableCellFrame*)(rs->frame);
const nsStylePosition* cellPosition;
- rs->frame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)cellPosition));
+ lastCellFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)cellPosition));
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nsTableFrame *tableParent;
- nsresult rv=GetTableFrame(rs->frame, tableParent);
+ nsresult rv=GetTableFrame(lastCellFrame, tableParent);
if ((NS_OK==rv) && (nsnull!=tableParent) && (nsnull!=tableParent->mColumnWidths))
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame *)rs->frame)->GetColIndex();
- PRInt32 colSpan = tableParent->GetEffectiveColSpan(colIndex, (nsTableCellFrame *)rs->frame);
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = tableParent->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i=0; iGetColumnWidth(colIndex);
break;
@@ -3581,12 +3726,12 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
{
parentWidth = cellPosition->mWidth.GetCoordValue();
// subtract out cell border and padding
- rs->frame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (PR_TRUE==gsDebugNT)
printf("%p: found a cell frame %p with fixed coord width %d, returning parentWidth %d\n",
- aReflowState.frame, rs->frame, cellPosition->mWidth.GetCoordValue(), parentWidth);
+ aReflowState.frame, lastCellFrame, cellPosition->mWidth.GetCoordValue(), parentWidth);
break;
}
}
@@ -3618,16 +3763,16 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
if (eStyleUnit_Auto == tablePosition->mWidth.GetUnit())
{
parentWidth = NS_UNCONSTRAINEDSIZE;
- if (nsnull != ((nsTableFrame*)rs->frame)->mColumnWidths)
+ if (nsnull != ((nsTableFrame*)(rs->frame))->mColumnWidths)
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame *)greatgrandchildFrame)->GetColIndex();
- PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = ((nsTableFrame*)(rs->frame))->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i = 0; iframe)->GetColumnWidth(i+colIndex);
+ parentWidth += ((nsTableFrame*)(rs->frame))->GetColumnWidth(i+colIndex);
// subtract out cell border and padding
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (PR_TRUE==gsDebugNT)
printf("%p: found a table frame %p with auto width, returning parentWidth %d from cell in col %d with span %d\n",
@@ -3642,13 +3787,13 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
}
else
{
- if (nsnull!=((nsTableFrame*)rs->frame)->mColumnWidths)
+ if (nsnull!=((nsTableFrame*)(rs->frame))->mColumnWidths)
{
parentWidth=0;
- PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
- PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
+ PRInt32 colIndex = lastCellFrame->GetColIndex();
+ PRInt32 colSpan = ((nsTableFrame*)(rs->frame))->GetEffectiveColSpan(colIndex, lastCellFrame);
for (PRInt32 i = 0; iframe)->GetColumnWidth(i+colIndex);
+ parentWidth += ((nsTableFrame*)(rs->frame))->GetColumnWidth(i+colIndex);
}
else
{
@@ -3659,17 +3804,9 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
{ // the table has been sized, so we can compute the available space for the child
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row group
- childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(childFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row
- grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the cell
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ // factor in the cell
+ lastCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(lastCellFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
}
else
@@ -3693,19 +3830,6 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
}
}
- if (nsnull==childFrame)
- childFrame = rs->frame;
- else if (nsnull==grandchildFrame)
- {
- grandchildFrame = childFrame;
- childFrame = rs->frame;
- }
- else
- {
- greatgrandchildFrame = grandchildFrame;
- grandchildFrame = childFrame;
- childFrame = rs->frame;
- }
rs = rs->parentReflowState;
}
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index 716664e3c18..97ef0dc38fc 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -90,7 +90,7 @@ public:
/** return PR_TRUE if aDisplayType represents a rowgroup of any sort
* (header, footer, or body)
*/
- PRBool IsRowGroup(PRInt32 aDisplayType);
+ PRBool IsRowGroup(PRInt32 aDisplayType) const;
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
@@ -368,6 +368,12 @@ protected:
*/
nscoord ComputeDesiredWidth(const nsHTMLReflowState& aReflowState) const;
+ nscoord ComputeDesiredHeight(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState,
+ nscoord aDefaultHeight);
+
+ nscoord GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState);
+
nscoord GetTopMarginFor(nsIPresContext& aCX,
InnerTableReflowState& aReflowState,
const nsMargin& aKidMargin);
@@ -524,7 +530,7 @@ public: /* ----- Cell Map public methods ----- */
* if mCellMap has been created, it is asked for the number of rows.
* otherwise, the content is enumerated and the rows are counted.
*/
- virtual PRInt32 GetRowCount();
+ virtual PRInt32 GetRowCount() const;
/** returns the number of columns in this table. */
virtual PRInt32 GetColCount();
@@ -605,7 +611,7 @@ private:
};
-inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType)
+inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
{
return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index 7929a818c98..2aca5b9f45c 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -174,55 +174,61 @@ nsTableRowFrame::InitChildren(PRInt32 aRowIndex)
/**
* Post-reflow hook. This is where the table row does its post-processing
*/
-NS_METHOD
-nsTableRowFrame::DidReflow(nsIPresContext& aPresContext,
- nsDidReflowStatus aStatus)
+void
+nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState)
{
- if (gsDebug) printf("Row %p DidReflow: begin mRect.h=%d, mCellMTM=%d, mCellMBM=%d\n",
+ if (gsDebug) printf("Row %p DidResize: begin mRect.h=%d, mCellMTM=%d, mCellMBM=%d\n",
this, mRect.height, mCellMaxTopMargin, mCellMaxBottomMargin);
- if (NS_FRAME_REFLOW_FINISHED == aStatus) {
- // Resize and re-align the cell frames based on our row height
- nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
- if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
- nsIFrame *cellFrame = mFirstChild;
- nsTableFrame* tableFrame;
- nsTableFrame::GetTableFrame(this, tableFrame);
- while (nsnull != cellFrame)
+ // Resize and re-align the cell frames based on our row height
+ nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
+ if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
+ nsIFrame *cellFrame = mFirstChild;
+ nsTableFrame* tableFrame;
+ nsTableFrame::GetTableFrame(this, tableFrame);
+ while (nsnull != cellFrame)
+ {
+ const nsStyleDisplay *kidDisplay;
+ cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
- const nsStyleDisplay *kidDisplay;
- cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, (nsTableCellFrame *)cellFrame);
+ if (gsDebug) printf("Row DidReflow: cellFrame %p ", cellFrame);
+ if (1==rowSpan)
{
- PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, (nsTableCellFrame *)cellFrame);
- if (gsDebug) printf("Row DidReflow: cellFrame %p ", cellFrame);
- if (1==rowSpan)
+ // resize the cell's height
+ nsSize cellFrameSize;
+ cellFrame->GetSize(cellFrameSize);
+ if (cellFrameSize.height!=cellHeight)
{
- // resize the cell's height
- nsSize cellFrameSize;
- cellFrame->GetSize(cellFrameSize);
cellFrame->SizeTo(cellFrameSize.width, cellHeight);
if (gsDebug) printf("given height %d\n", cellHeight);
// realign cell content based on the new height
- ((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(&aPresContext);
- }
- else
- {
- if (gsDebug)
- {
- nsSize cellFrameSize;
- cellFrame->GetSize(cellFrameSize);
- printf("has rowspan %d and height %d, unchanged.\n", rowSpan, cellFrameSize.height);
- }
+ nsHTMLReflowMetrics desiredSize(nsnull);
+ nsHTMLReflowState kidReflowState(aPresContext, cellFrame,
+ aReflowState, nsSize(cellFrameSize.width, cellHeight),
+ eReflowReason_Resize);
+ nsReflowStatus status;
+ ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status);
+ ((nsTableCellFrame *)cellFrame)->VerticallyAlignChild();
+ }
+ }
+ else
+ {
+ if (gsDebug)
+ {
+ nsSize cellFrameSize;
+ cellFrame->GetSize(cellFrameSize);
+ printf("has rowspan %d and height %d, unchanged.\n", rowSpan, cellFrameSize.height);
}
}
- // Get the next cell
- cellFrame->GetNextSibling(cellFrame);
}
+ // Get the next cell
+ cellFrame->GetNextSibling(cellFrame);
}
// Let our base class do the usual work
- if (gsDebug) printf("Row DidReflow: returning superclass DidReflow.\n");
- return nsContainerFrame::DidReflow(aPresContext, aStatus);
+ if (gsDebug) printf("Row DidResize: returning NS_OK.\n");
}
void nsTableRowFrame::ResetMaxChildHeight()
@@ -449,6 +455,22 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
}
}
+nsIFrame * nsTableRowFrame::GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild)
+{
+ NS_ASSERTION(nsnull!=aCurrentChild, "bad arg");
+
+ nsIFrame *result=nsnull;
+ aCurrentChild->GetNextSibling(result);
+ return result;
+}
+
+nsIFrame * nsTableRowFrame::GetFirstChildForDirection(PRUint8 aDir)
+{
+ nsIFrame *result=nsnull;
+ result = mFirstChild;
+ return result;
+}
+
/**
* Called for a resize reflow. Typically because the column widths have
* changed. Reflows all the existing table cell frames
@@ -461,18 +483,22 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
if (nsnull == mFirstChild)
return NS_OK;
- nsresult rv=NS_OK;
- nsSize kidMaxElementSize;
- PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
- nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
- &kidMaxElementSize : nsnull;
- nscoord maxCellTopMargin = 0;
- nscoord maxCellBottomMargin = 0;
+ nsresult rv=NS_OK;
+ nsSize kidMaxElementSize;
+ PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
+ nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
+ &kidMaxElementSize : nsnull;
+ nscoord maxCellTopMargin = 0;
+ nscoord maxCellBottomMargin = 0;
nscoord cellSpacing = aReflowState.tableFrame->GetCellSpacing();
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
if (PR_TRUE==gsDebug) printf("Row %p: Resize Reflow\n", this);
+
// Reflow each of our existing cell frames
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
+ const nsStyleDisplay *rowDisplay;
+ GetStyleData(eStyleStruct_Display, (nsStyleStruct*&)rowDisplay);
+ nsIFrame* kidFrame=GetFirstChildForDirection(rowDisplay->mDirection);
+ for (kidFrame; nsnull != kidFrame; )
{
const nsStyleDisplay *kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
@@ -621,7 +647,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
}
// Get the next child
- kidFrame->GetNextSibling(kidFrame);
+ kidFrame = GetNextChildForDirection(rowDisplay->mDirection, kidFrame);
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
if ((nsnull==kidFrame) && (cellColSpan>1))
diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h
index 9625fa66992..65d6d169818 100644
--- a/mozilla/layout/tables/nsTableRowFrame.h
+++ b/mozilla/layout/tables/nsTableRowFrame.h
@@ -93,8 +93,8 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
- NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
- nsDidReflowStatus aStatus);
+ virtual void DidResize(nsIPresContext& aPresContext,
+ const nsHTMLReflowState& aReflowState);
/** @see nsContainerFrame::CreateContinuingFrame */
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
@@ -214,6 +214,9 @@ protected:
nscoord ComputeCellAvailWidth(const RowReflowState& aState,
nsIFrame* aKidFrame) const;
+ nsIFrame * GetFirstChildForDirection(PRUint8 aDir);
+ nsIFrame * GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild);
+
/**
* Called for a resize reflow. Typically because the column widths have
* changed. Reflows all the existing table cell frames
diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
index be496ce96e2..8bae925ef96 100644
--- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
@@ -601,12 +601,15 @@ NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext
return rv;
}
-/**
- */
-void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize)
+/* CalculateRowHeights provides default heights for all rows in the rowgroup.
+ * Actual row heights are ultimately determined by the table, when the table
+ * height attribute is factored in.
+ */
+void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState)
{
- if (gsDebug) printf("TRGF ShrinkWrapChildren begin\n");
+ if (gsDebug) printf("TRGF CalculateRowHeights begin\n");
// iterate children and for each row get its height
PRBool atLeastOneRowSpanningCell = PR_FALSE;
nscoord topInnerMargin = 0;
@@ -717,7 +720,7 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
cellFrameSize.height, heightOfRowsSpanned);
cellFrame->SizeTo(cellFrameSize.width, heightOfRowsSpanned);
// Realign cell content based on new height
- ((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
+ ((nsTableCellFrame*)cellFrame)->VerticallyAlignChild();
}
/* otherwise, distribute the excess height to the rows effected.
* push all subsequent rows down by the total change in height of all the rows above it
@@ -781,6 +784,20 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
}
}
+ // finally, notify the rows of their new heights
+ rowFrame = mFirstChild;
+ while (nsnull != rowFrame)
+ {
+ const nsStyleDisplay *childDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
+ {
+ ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
+ }
+ // Get the next row
+ rowFrame->GetNextSibling(rowFrame);
+ }
+
// Adjust our desired size
aDesiredSize.height = rowGroupHeight;
@@ -907,7 +924,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height = state.y;
// shrink wrap rows to height of tallest cell in that row
- ShrinkWrapChildren(&aPresContext, aDesiredSize);
+ if (eReflowReason_Initial != aReflowState.reason) {
+ CalculateRowHeights(aPresContext, aDesiredSize, aReflowState);
+ }
}
if (gsDebug==PR_TRUE)
@@ -1337,3 +1356,4 @@ nsTableRowGroupFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TableRowGroup", aResult);
}
+
diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.h b/mozilla/layout/tables/nsTableRowGroupFrame.h
index c2bfd335b03..12bbfbb8dfd 100644
--- a/mozilla/layout/tables/nsTableRowGroupFrame.h
+++ b/mozilla/layout/tables/nsTableRowGroupFrame.h
@@ -133,8 +133,9 @@ protected:
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
- void ShrinkWrapChildren(nsIPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize);
+ void CalculateRowHeights(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState);
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow