diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
index 211e19b3a3e..897aa7d071a 100644
--- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
+++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
@@ -1322,6 +1322,12 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext,
processChildren = PR_TRUE;
break;
+ case NS_STYLE_DISPLAY_TABLE_CAPTION:
+ // XXX We should check for being inside of a table row frame...
+ rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame, NS_BODY_NO_AUTO_MARGINS);
+ processChildren = PR_TRUE;
+ break;
+
default:
// Don't create any frame for content that's not displayed...
break;
diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp
index 211e19b3a3e..897aa7d071a 100644
--- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp
+++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp
@@ -1322,6 +1322,12 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext,
processChildren = PR_TRUE;
break;
+ case NS_STYLE_DISPLAY_TABLE_CAPTION:
+ // XXX We should check for being inside of a table row frame...
+ rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame, NS_BODY_NO_AUTO_MARGINS);
+ processChildren = PR_TRUE;
+ break;
+
default:
// Don't create any frame for content that's not displayed...
break;
diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index c4655bb3941..a42d4660c53 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -140,6 +140,16 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
AssignPreliminaryColumnWidths();
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
+ if (nsnull!=aMaxElementSize)
+ {
+ SetMaxElementSize(aMaxElementSize);
+ }
+
+ return result;
+}
+
+void BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize)
+{
if (nsnull!=aMaxElementSize)
{
aMaxElementSize->height = 0;
@@ -165,8 +175,6 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
printf("%p BTLS::Init setting aMaxElementSize->width = %d\n",
mTableFrame, aMaxElementSize->width);
}
-
- return result;
}
PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle,
diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
index 74ea0a8f9a9..b7f9ff43687 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
@@ -86,11 +86,13 @@ public:
/** call once every time any table thing changes (content, structure, or style) */
virtual PRBool Initialize(nsSize* aMaxElementSize);
+ virtual void SetMaxElementSize(nsSize* aMaxElementSize);
+
/** Called during resize reflow to determine the new column widths
* @param aTableStyle - the resolved style for mTableFrame
- * @param aReflowState - the reflow state for mTableFrame
- * @param aMaxWidth - the computed max width for columns to fit into
- */
+ * @param aReflowState - the reflow state for mTableFrame
+ * @param aMaxWidth - the computed max width for columns to fit into
+ */
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
const nsHTMLReflowState& aReflowState,
nscoord aMaxWidth);
diff --git a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
index 7f3cad18577..509f72c3441 100644
--- a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
@@ -34,6 +34,11 @@ public:
*/
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
+ /** compute the max-element-size for the table
+ * @param aMaxElementSize [OUT] width field set to the min legal width of the table
+ */
+ virtual void SetMaxElementSize(nsSize* aMaxElementSize)=0;
+
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
* @param aTableStyle the resolved style for the table
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index 50a46d7b7de..7ec69a7f919 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -1906,6 +1906,7 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
}
}
+ //XXX: this should call into layout strategy to get the width field
if (nsnull != aMaxElementSize)
{
nsMargin borderPadding;
@@ -3283,6 +3284,12 @@ nscoord nsTableFrame::GetMaxTableWidth()
return result;
}
+void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize)
+{
+ if (nsnull!=mTableLayoutStrategy)
+ mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize);
+}
+
/* ----- debugging methods ----- */
NS_METHOD nsTableFrame::List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index 6697b229458..df686311fea 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -480,6 +480,11 @@ public: /* ----- Cell Map public methods ----- */
/** return the maximum width of the table caption. Return 0 if the max width is unknown. */
nscoord GetMaxTableWidth();
+ /** compute the max-element-size for the table
+ * @param aMaxElementSize [OUT] width field set to the min legal width of the table
+ */
+ void SetMaxElementSize(nsSize* aMaxElementSize);
+
private:
void DebugPrintCount() const; // Debugging routine
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
index 992e2a7c46e..668356ae559 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
@@ -34,7 +34,7 @@
#ifdef NS_DEBUG
static PRBool gsDebug = PR_FALSE;
static PRBool gsTiming = PR_FALSE;
-static PRBool gsDebugIR = PR_TRUE;
+static PRBool gsDebugIR = PR_FALSE;
//#define NOISY
//#define NOISY_FLOW
#define NOISY_MARGINS
@@ -253,6 +253,7 @@ nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext& aPresContex
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ if (PR_TRUE==gsDebugIR) printf("\nTOF IR: IncrementalReflow\n");
nsresult rv = NS_OK;
// determine if this frame is the target or not
@@ -308,8 +309,95 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- if (PR_TRUE==gsDebugIR) printf("TOF IR: IR_TargetIsCaptionFrame\n");
nsresult rv;
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: IR_TargetIsCaptionFrame\n");
+ PRBool innerTableNeedsReflow=PR_FALSE;
+ // remember the old width and height
+ nsRect priorCaptionRect;
+ mCaptionFrame->GetRect(priorCaptionRect);
+ // if the reflow type is a style change, also remember the prior style
+ nsIReflowCommand::ReflowType reflowCommandType;
+ aReflowState.reflowState.reflowCommand->GetType(reflowCommandType);
+ const nsStyleText* priorCaptionTextStyle=nsnull;
+ if (nsIReflowCommand::StyleChanged==reflowCommandType)
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)priorCaptionTextStyle));
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: prior caption width=%d height=%d, minWidth=%d\n",
+ priorCaptionRect.width, priorCaptionRect.height,
+ mMinCaptionWidth);
+
+ // pass along the reflow command to the caption
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: passing down incremental reflow command to caption.\n");
+ nsSize captionMES(0,0);
+ nsHTMLReflowMetrics captionSize(&captionMES);
+ nsHTMLReflowState captionReflowState(mCaptionFrame, aReflowState.reflowState,
+ nsSize(mRect.width,
+ aReflowState.reflowState.maxSize.height));
+ rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus);
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width=%d height=%d, minCaptionWidth=%d\n",
+ rv, captionSize.width, captionSize.height, captionMES.width);
+ if (NS_FAILED(rv))
+ return rv;
+ if (mMinCaptionWidth != captionMES.width)
+ { // set the new caption min width, and set state to reflow the inner table if necessary
+ mMinCaptionWidth = captionMES.width;
+ if (mMinCaptionWidth>mRect.width)
+ innerTableNeedsReflow=PR_TRUE;
+ }
+
+ // check if the caption alignment changed axis
+ if (nsIReflowCommand::StyleChanged==reflowCommandType)
+ {
+ const nsStyleText* captionTextStyle;
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
+ if (PR_TRUE==IR_CaptionChangedAxis(priorCaptionTextStyle, captionTextStyle))
+ innerTableNeedsReflow=PR_TRUE;
+ }
+
+ // if we've determined that the inner table needs to be reflowed, do it here
+ nsSize innerTableSize;
+ if (PR_TRUE==innerTableNeedsReflow)
+ {
+ if (PR_TRUE==gsDebugIR) printf("inner table needs resize reflow.\n");
+ // Compute the width to use for the table. In the case of an auto sizing
+ // table this represents the maximum available width
+ nscoord tableWidth = GetTableWidth(aReflowState.reflowState);
+
+ // If the caption max element size is larger, then use it instead.
+ // XXX: caption align = left|right ignored here!
+ if (mMinCaptionWidth > tableWidth) {
+ tableWidth = mMinCaptionWidth;
+ }
+ nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
+ nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
+ nsSize(tableWidth, aReflowState.reflowState.maxSize.height),
+ eReflowReason_Resize);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ innerTableSize.SizeTo(innerSize.width, innerSize.height);
+ // set maxElementSize width if requested
+ if (nsnull != aDesiredSize.maxElementSize)
+ {
+ ((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
+ if (mMinCaptionWidth > aDesiredSize.maxElementSize->width)
+ {
+ aDesiredSize.maxElementSize->width = mMinCaptionWidth;
+ }
+ }
+ }
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("skipping inner table resize reflow.\n");
+ nsRect innerTableRect;
+ mInnerTableFrame->GetRect(innerTableRect);
+ innerTableSize.SizeTo(innerTableRect.width, innerTableRect.height);
+ }
+
+ // regardless of what we've done up to this point, place the caption and inner table
+ rv = SizeAndPlaceChildren(innerTableSize,
+ nsSize (captionSize.width, captionSize.height),
+ aReflowState);
+
return rv;
}
@@ -322,7 +410,7 @@ nsresult nsTableOuterFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
nsIReflowCommand::ReflowType type;
aReflowState.reflowState.reflowCommand->GetType(type);
nsIFrame *objectFrame;
- aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
+ aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
if (PR_TRUE==gsDebugIR) printf("TOF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
switch (type)
{
@@ -455,8 +543,12 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
captionDimChanged=PR_TRUE;
}
}
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping caption reflow\n");
+ }
if (PR_TRUE==gsDebugIR) printf("TOF IR: captionDimChanged = %d\n", captionDimChanged);
- // XXX: make this it's own method
+ // XXX: should just call SizeAndPlaceChildren regardless
// find where to place the caption
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
@@ -479,11 +571,8 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
captionRect.SizeTo(oldCaptionRect.width, oldCaptionRect.height);
mCaptionFrame->SetRect(captionRect);
if (PR_TRUE==gsDebugIR)
- {
- printf("TOF IR: captionRect=");
- stdout << captionRect;
- printf("\n");
- }
+ printf(" TOF IR: captionRect=%d %d %d %d\n", captionRect.x, captionRect.y,
+ captionRect.width, captionRect.height);
}
}
@@ -521,29 +610,11 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
}
nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
mInnerTableFrame->SetRect(innerRect);
- if (PR_TRUE==gsDebugIR)
- {
- printf("TOF IR: innerRect=");
- stdout << innerRect;
- printf("\n");
- }
- // set out params
- // XXX: make this its own method
- /* if we're incomplete, take up all the remaining height so we don't waste time
- * trying to lay out in a slot that we know isn't tall enough to fit our minimum.
- * otherwise, we're as tall as our kids want us to be */
- if (NS_FRAME_IS_NOT_COMPLETE(aStatus))
- aDesiredSize.height = aReflowState.reflowState.maxSize.height;
- else
- { // this should be the caption height + inner table height + space between them
- aDesiredSize.height = aReflowState.y;
- }
- // Return our desired rect
- aDesiredSize.width = aReflowState.innerTableMaxSize.width;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- if (PR_TRUE==gsDebugIR) printf("TOF IR: aDS.width=%d, aDS.height=%d\n",
- aDesiredSize.width, aDesiredSize.height);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: innerRect=%d %d %d %d\n", innerRect.x, innerRect.y,
+ innerRect.width, innerRect.height);
+
+ aReflowState.innerTableMaxSize.width = innerSize.width;
return rv;
}
@@ -569,8 +640,10 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
// make aCaptionFrame this table's caption
mCaptionFrame = aCaptionFrame;
+ mInnerTableFrame->SetNextSibling(mCaptionFrame);
// reflow the caption frame, getting it's MES
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: initial-reflowing caption\n");
nsSize maxElementSize;
nsHTMLReflowMetrics captionSize(&maxElementSize);
nsHTMLReflowState captionReflowState(mCaptionFrame, aReflowState.reflowState,
@@ -581,87 +654,53 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
if (NS_OK == mCaptionFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow))
{ // initial reflow of the caption
htmlReflow->WillReflow(aPresContext);
- htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ rv = htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width =%d, height = %d, minWidth=%d\n",
+ rv, captionSize.width, captionSize.height, maxElementSize.width);
mMinCaptionWidth = maxElementSize.width;
// get the caption's alignment
const nsStyleText* captionTextStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- if ((captionTextStyle->mVerticalAlign.GetUnit()!=eStyleUnit_Enumerated) || // default is "top"
+ if (PR_TRUE || // XXX: this is a hack because we don't support left|right captions yet
+ (captionTextStyle->mVerticalAlign.GetUnit()!=eStyleUnit_Enumerated) || // default is "top"
((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
((captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_TOP) ||
(captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))))
{
// XXX: caption align = left|right ignored here!
- // if the caption's MES > TMW, reflow the inner table
- nscoord tableMaxWidth = ((nsTableFrame *)mInnerTableFrame)->GetMaxTableWidth();
+ // if the caption's MES > table width, reflow the inner table
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
- if ((oldCaptionMES != mMinCaptionWidth) && (mMinCaptionWidth > tableMaxWidth))
+ if ((oldCaptionMES != mMinCaptionWidth) && (mMinCaptionWidth > mRect.width))
{
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: resize-reflowing inner table\n");
nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
- nsSize(mMinCaptionWidth, aReflowState.reflowState.maxSize.height));
+ nsSize(mMinCaptionWidth, aReflowState.reflowState.maxSize.height),
+ eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: inner table reflow returned %d with width =%d, height = %d\n",
+ rv, innerSize.width, innerSize.height);
}
else
{ // set innerSize as if the inner table were reflowed
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping reflow of inner table\n");
innerSize.height = mRect.height;
innerSize.width = mRect.width;
}
// set maxElementSize width if requested
- if (nsnull != aDesiredSize.maxElementSize) {
- if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
+ if (nsnull != aDesiredSize.maxElementSize)
+ {
+ ((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
+ if (mMinCaptionWidth > aDesiredSize.maxElementSize->width)
+ {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
}
- // find where to place the caption
- nsMargin captionMargin;
- const nsStyleSpacing* spacing;
- mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
- spacing->CalcMarginFor(mCaptionFrame, captionMargin);
- // Compute the caption's y-origin
- nscoord captionY = captionMargin.top;
- const nsStyleText* captionTextStyle;
- mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
- (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
- {
- captionY += innerSize.height;
- }
- // Place the caption
- nsRect captionRect(captionMargin.left, captionY, 0, 0);
- captionRect.SizeTo(captionSize.width, captionSize.height);
- mCaptionFrame->SetRect(captionRect);
- // Place the inner table
- nscoord innerY;
- if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
- (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
-
- { // bottom caption
- innerY = 0;
- aReflowState.y = captionRect.YMost() + captionMargin.bottom;
- }
- else
- { // top caption
- innerY = captionRect.YMost() + captionMargin.bottom;
- aReflowState.y = innerY + innerSize.height;
- }
- nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
- mInnerTableFrame->SetRect(innerRect);
- /* if we're incomplete, take up all the remaining height so we don't waste time
- * trying to lay out in a slot that we know isn't tall enough to fit our minimum.
- * otherwise, we're as tall as our kids want us to be */
- if (NS_FRAME_IS_NOT_COMPLETE(aStatus))
- aDesiredSize.height = aReflowState.reflowState.maxSize.height;
- else
- aDesiredSize.height = aReflowState.y;
- // Return our desired rect
- aDesiredSize.width = aReflowState.innerTableMaxSize.width;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- }
- else
- {
- rv = NS_ERROR_NOT_IMPLEMENTED;
- if (PR_TRUE==gsDebugIR) printf("TOF IR: left|right caption not implemented.\n");
+
+ rv = SizeAndPlaceChildren(nsSize (innerSize.width, innerSize.height),
+ nsSize (captionSize.width, captionSize.height),
+ aReflowState);
}
}
return rv;
@@ -679,20 +718,34 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
// get the caption's alignment
const nsStyleText* captionTextStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- // if the caption's MES > TMW, reflow the inner table minus the MES
- nscoord tableMaxWidth = ((nsTableFrame *)mInnerTableFrame)->GetMaxTableWidth();
+ // if the caption's MES > table width, reflow the inner table minus the MES
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
nscoord oldMinCaptionWidth = mMinCaptionWidth;
// set the cached min caption width to 0 here, so it can't effect inner table reflow
mMinCaptionWidth = 0;
mCaptionFrame=nsnull;
- if (oldMinCaptionWidth > tableMaxWidth)
+ mInnerTableFrame->SetNextSibling(nsnull);
+ if (oldMinCaptionWidth > mRect.width)
{ // the old caption width had an effect on the inner table width, so reflow the inner table
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: reflowing inner table\n");
nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
nsSize(aReflowState.reflowState.maxSize.width,
aReflowState.reflowState.maxSize.height));
// ReflowChild sets MES
- ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ // set the output state
+ aReflowState.innerTableMaxSize.width = innerSize.width;
+ aReflowState.y = innerSize.height;
+ }
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping reflow of inner table\n");
+ nsRect innerRect;
+ mInnerTableFrame->GetRect(innerRect);
+ aReflowState.innerTableMaxSize.width = innerRect.width;
+ aReflowState.y = innerRect.height;
}
// if the caption was a top caption, move the inner table to the correct offset
if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
@@ -700,11 +753,6 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
{
mInnerTableFrame->MoveTo(0,0);
}
- // Return our desired rect
- aDesiredSize.width = innerSize.width; //aReflowState.innerTableMaxSize.width;
- aDesiredSize.height = innerSize.height;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
}
else
rv = NS_ERROR_ILLEGAL_VALUE;
@@ -712,6 +760,65 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
return rv;
}
+PRBool nsTableOuterFrame::IR_CaptionChangedAxis(const nsStyleText* aOldStyle,
+ const nsStyleText* aNewStyle) const
+{
+ PRBool result = PR_FALSE;
+ //XXX: write me to support left|right captions!
+ return result;
+}
+
+nsresult nsTableOuterFrame::SizeAndPlaceChildren(const nsSize & aInnerSize,
+ const nsSize & aCaptionSize,
+ OuterTableReflowState& aReflowState)
+{
+ if (PR_TRUE==gsDebugIR) printf(" TOF IR: SizeAndPlaceChildren\n");
+ nsresult rv = NS_OK;
+ // find where to place the caption
+ nsMargin captionMargin;
+ const nsStyleSpacing* spacing;
+ mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
+ spacing->CalcMarginFor(mCaptionFrame, captionMargin);
+ // Compute the caption's y-origin
+ nscoord captionY = captionMargin.top;
+ const nsStyleText* captionTextStyle;
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
+ if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
+ (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
+ {
+ captionY += aInnerSize.height;
+ }
+ // Place the caption
+ nsRect captionRect(captionMargin.left, captionY, 0, 0);
+ captionRect.SizeTo(aCaptionSize.width, aCaptionSize.height);
+ mCaptionFrame->SetRect(captionRect);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: captionRect=%d %d %d %d\n", captionRect.x, captionRect.y,
+ captionRect.width, captionRect.height);
+
+ // Place the inner table
+ nscoord innerY;
+ if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
+ (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
+
+ { // bottom caption
+ innerY = 0;
+ aReflowState.y = captionRect.YMost() + captionMargin.bottom;
+ }
+ else
+ { // top caption
+ innerY = captionRect.YMost() + captionMargin.bottom;
+ aReflowState.y = innerY + aInnerSize.height;
+ }
+ nsRect innerRect(0, innerY, aInnerSize.width, aInnerSize.height);
+ mInnerTableFrame->SetRect(innerRect);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: innerRect=%d %d %d %d\n", innerRect.x, innerRect.y,
+ innerRect.width, innerRect.height);
+ aReflowState.innerTableMaxSize.width = aInnerSize.width;
+ return rv;
+}
+
/**
* Called by the Reflow() member function to compute the table width
*/
@@ -787,6 +894,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ nsresult rv = NS_OK;
if (PR_TRUE==gsDebug)
printf("%p: nsTableOuterFrame::Reflow : maxSize=%d,%d\n",
this, aReflowState.maxSize.width, aReflowState.maxSize.height);
@@ -808,11 +916,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Initialize our local reflow state
OuterTableReflowState state(aPresContext, aReflowState);
if (eReflowReason_Incremental == aReflowState.reason) {
- IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
-
- // Return our desired rect
- aDesiredSize.width = state.innerTableMaxSize.width;
-
+ rv = IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
} else {
if (eReflowReason_Initial == aReflowState.reason) {
//KIPP/TROY: uncomment the following line for your own testing, do not check it in
@@ -833,7 +937,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
if (NS_OK == mCaptionFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->WillReflow(aPresContext);
- htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ rv = htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mMinCaptionWidth = maxElementSize.width;
}
}
@@ -858,7 +962,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
nsSize(tableWidth, aReflowState.maxSize.height));
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
- ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
// Table's max element size is the MAX of the caption's max element size
// and the inner table's max element size...
@@ -946,7 +1050,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
- if (gsDebug==PR_TRUE)
+ if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
{
if (nsnull!=aDesiredSize.maxElementSize)
printf("%p: Outer frame Reflow complete, returning %s with aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n",
@@ -965,7 +1069,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
endTime-startTime, this);/* XXX need to use LL_* macros! */
}
- return NS_OK;
+ return rv;
}
// Position and size aKidFrame and update our reflow state. The origin of
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h
index ed5bd1231f7..cd563bc0970 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.h
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h
@@ -22,6 +22,7 @@
#include "nsContainerFrame.h"
struct OuterTableReflowState;
+struct nsStyleText;
/**
* main frame for an nsTable content object,
@@ -168,6 +169,13 @@ protected:
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
+ PRBool IR_CaptionChangedAxis(const nsStyleText* aOldStyle,
+ const nsStyleText* aNewStyle) const;
+
+ nsresult SizeAndPlaceChildren(const nsSize & aInnerSize,
+ const nsSize & aCaptionSize,
+ OuterTableReflowState& aReflowState);
+
nsresult AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,
diff --git a/mozilla/layout/html/tests/TableIncrementalReflow.html b/mozilla/layout/html/tests/TableIncrementalReflow.html
new file mode 100644
index 00000000000..4929d1029f9
--- /dev/null
+++ b/mozilla/layout/html/tests/TableIncrementalReflow.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+ | table without a caption |
+
+
+
+
+
+
+ here is a caption
+
+
+ | table with a caption |
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp
index 211e19b3a3e..897aa7d071a 100644
--- a/mozilla/layout/style/nsHTMLStyleSheet.cpp
+++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp
@@ -1322,6 +1322,12 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext,
processChildren = PR_TRUE;
break;
+ case NS_STYLE_DISPLAY_TABLE_CAPTION:
+ // XXX We should check for being inside of a table row frame...
+ rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame, NS_BODY_NO_AUTO_MARGINS);
+ processChildren = PR_TRUE;
+ break;
+
default:
// Don't create any frame for content that's not displayed...
break;
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index c4655bb3941..a42d4660c53 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -140,6 +140,16 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
AssignPreliminaryColumnWidths();
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
+ if (nsnull!=aMaxElementSize)
+ {
+ SetMaxElementSize(aMaxElementSize);
+ }
+
+ return result;
+}
+
+void BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize)
+{
if (nsnull!=aMaxElementSize)
{
aMaxElementSize->height = 0;
@@ -165,8 +175,6 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
printf("%p BTLS::Init setting aMaxElementSize->width = %d\n",
mTableFrame, aMaxElementSize->width);
}
-
- return result;
}
PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle,
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h
index 74ea0a8f9a9..b7f9ff43687 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h
@@ -86,11 +86,13 @@ public:
/** call once every time any table thing changes (content, structure, or style) */
virtual PRBool Initialize(nsSize* aMaxElementSize);
+ virtual void SetMaxElementSize(nsSize* aMaxElementSize);
+
/** Called during resize reflow to determine the new column widths
* @param aTableStyle - the resolved style for mTableFrame
- * @param aReflowState - the reflow state for mTableFrame
- * @param aMaxWidth - the computed max width for columns to fit into
- */
+ * @param aReflowState - the reflow state for mTableFrame
+ * @param aMaxWidth - the computed max width for columns to fit into
+ */
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
const nsHTMLReflowState& aReflowState,
nscoord aMaxWidth);
diff --git a/mozilla/layout/tables/nsITableLayoutStrategy.h b/mozilla/layout/tables/nsITableLayoutStrategy.h
index 7f3cad18577..509f72c3441 100644
--- a/mozilla/layout/tables/nsITableLayoutStrategy.h
+++ b/mozilla/layout/tables/nsITableLayoutStrategy.h
@@ -34,6 +34,11 @@ public:
*/
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
+ /** compute the max-element-size for the table
+ * @param aMaxElementSize [OUT] width field set to the min legal width of the table
+ */
+ virtual void SetMaxElementSize(nsSize* aMaxElementSize)=0;
+
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
* @param aTableStyle the resolved style for the table
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index 50a46d7b7de..7ec69a7f919 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -1906,6 +1906,7 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
}
}
+ //XXX: this should call into layout strategy to get the width field
if (nsnull != aMaxElementSize)
{
nsMargin borderPadding;
@@ -3283,6 +3284,12 @@ nscoord nsTableFrame::GetMaxTableWidth()
return result;
}
+void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize)
+{
+ if (nsnull!=mTableLayoutStrategy)
+ mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize);
+}
+
/* ----- debugging methods ----- */
NS_METHOD nsTableFrame::List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index 6697b229458..df686311fea 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -480,6 +480,11 @@ public: /* ----- Cell Map public methods ----- */
/** return the maximum width of the table caption. Return 0 if the max width is unknown. */
nscoord GetMaxTableWidth();
+ /** compute the max-element-size for the table
+ * @param aMaxElementSize [OUT] width field set to the min legal width of the table
+ */
+ void SetMaxElementSize(nsSize* aMaxElementSize);
+
private:
void DebugPrintCount() const; // Debugging routine
diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp
index 992e2a7c46e..668356ae559 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.cpp
+++ b/mozilla/layout/tables/nsTableOuterFrame.cpp
@@ -34,7 +34,7 @@
#ifdef NS_DEBUG
static PRBool gsDebug = PR_FALSE;
static PRBool gsTiming = PR_FALSE;
-static PRBool gsDebugIR = PR_TRUE;
+static PRBool gsDebugIR = PR_FALSE;
//#define NOISY
//#define NOISY_FLOW
#define NOISY_MARGINS
@@ -253,6 +253,7 @@ nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext& aPresContex
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ if (PR_TRUE==gsDebugIR) printf("\nTOF IR: IncrementalReflow\n");
nsresult rv = NS_OK;
// determine if this frame is the target or not
@@ -308,8 +309,95 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- if (PR_TRUE==gsDebugIR) printf("TOF IR: IR_TargetIsCaptionFrame\n");
nsresult rv;
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: IR_TargetIsCaptionFrame\n");
+ PRBool innerTableNeedsReflow=PR_FALSE;
+ // remember the old width and height
+ nsRect priorCaptionRect;
+ mCaptionFrame->GetRect(priorCaptionRect);
+ // if the reflow type is a style change, also remember the prior style
+ nsIReflowCommand::ReflowType reflowCommandType;
+ aReflowState.reflowState.reflowCommand->GetType(reflowCommandType);
+ const nsStyleText* priorCaptionTextStyle=nsnull;
+ if (nsIReflowCommand::StyleChanged==reflowCommandType)
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)priorCaptionTextStyle));
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: prior caption width=%d height=%d, minWidth=%d\n",
+ priorCaptionRect.width, priorCaptionRect.height,
+ mMinCaptionWidth);
+
+ // pass along the reflow command to the caption
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: passing down incremental reflow command to caption.\n");
+ nsSize captionMES(0,0);
+ nsHTMLReflowMetrics captionSize(&captionMES);
+ nsHTMLReflowState captionReflowState(mCaptionFrame, aReflowState.reflowState,
+ nsSize(mRect.width,
+ aReflowState.reflowState.maxSize.height));
+ rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus);
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width=%d height=%d, minCaptionWidth=%d\n",
+ rv, captionSize.width, captionSize.height, captionMES.width);
+ if (NS_FAILED(rv))
+ return rv;
+ if (mMinCaptionWidth != captionMES.width)
+ { // set the new caption min width, and set state to reflow the inner table if necessary
+ mMinCaptionWidth = captionMES.width;
+ if (mMinCaptionWidth>mRect.width)
+ innerTableNeedsReflow=PR_TRUE;
+ }
+
+ // check if the caption alignment changed axis
+ if (nsIReflowCommand::StyleChanged==reflowCommandType)
+ {
+ const nsStyleText* captionTextStyle;
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
+ if (PR_TRUE==IR_CaptionChangedAxis(priorCaptionTextStyle, captionTextStyle))
+ innerTableNeedsReflow=PR_TRUE;
+ }
+
+ // if we've determined that the inner table needs to be reflowed, do it here
+ nsSize innerTableSize;
+ if (PR_TRUE==innerTableNeedsReflow)
+ {
+ if (PR_TRUE==gsDebugIR) printf("inner table needs resize reflow.\n");
+ // Compute the width to use for the table. In the case of an auto sizing
+ // table this represents the maximum available width
+ nscoord tableWidth = GetTableWidth(aReflowState.reflowState);
+
+ // If the caption max element size is larger, then use it instead.
+ // XXX: caption align = left|right ignored here!
+ if (mMinCaptionWidth > tableWidth) {
+ tableWidth = mMinCaptionWidth;
+ }
+ nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
+ nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
+ nsSize(tableWidth, aReflowState.reflowState.maxSize.height),
+ eReflowReason_Resize);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ innerTableSize.SizeTo(innerSize.width, innerSize.height);
+ // set maxElementSize width if requested
+ if (nsnull != aDesiredSize.maxElementSize)
+ {
+ ((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
+ if (mMinCaptionWidth > aDesiredSize.maxElementSize->width)
+ {
+ aDesiredSize.maxElementSize->width = mMinCaptionWidth;
+ }
+ }
+ }
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("skipping inner table resize reflow.\n");
+ nsRect innerTableRect;
+ mInnerTableFrame->GetRect(innerTableRect);
+ innerTableSize.SizeTo(innerTableRect.width, innerTableRect.height);
+ }
+
+ // regardless of what we've done up to this point, place the caption and inner table
+ rv = SizeAndPlaceChildren(innerTableSize,
+ nsSize (captionSize.width, captionSize.height),
+ aReflowState);
+
return rv;
}
@@ -322,7 +410,7 @@ nsresult nsTableOuterFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
nsIReflowCommand::ReflowType type;
aReflowState.reflowState.reflowCommand->GetType(type);
nsIFrame *objectFrame;
- aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
+ aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
if (PR_TRUE==gsDebugIR) printf("TOF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
switch (type)
{
@@ -455,8 +543,12 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
captionDimChanged=PR_TRUE;
}
}
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping caption reflow\n");
+ }
if (PR_TRUE==gsDebugIR) printf("TOF IR: captionDimChanged = %d\n", captionDimChanged);
- // XXX: make this it's own method
+ // XXX: should just call SizeAndPlaceChildren regardless
// find where to place the caption
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
@@ -479,11 +571,8 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
captionRect.SizeTo(oldCaptionRect.width, oldCaptionRect.height);
mCaptionFrame->SetRect(captionRect);
if (PR_TRUE==gsDebugIR)
- {
- printf("TOF IR: captionRect=");
- stdout << captionRect;
- printf("\n");
- }
+ printf(" TOF IR: captionRect=%d %d %d %d\n", captionRect.x, captionRect.y,
+ captionRect.width, captionRect.height);
}
}
@@ -521,29 +610,11 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
}
nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
mInnerTableFrame->SetRect(innerRect);
- if (PR_TRUE==gsDebugIR)
- {
- printf("TOF IR: innerRect=");
- stdout << innerRect;
- printf("\n");
- }
- // set out params
- // XXX: make this its own method
- /* if we're incomplete, take up all the remaining height so we don't waste time
- * trying to lay out in a slot that we know isn't tall enough to fit our minimum.
- * otherwise, we're as tall as our kids want us to be */
- if (NS_FRAME_IS_NOT_COMPLETE(aStatus))
- aDesiredSize.height = aReflowState.reflowState.maxSize.height;
- else
- { // this should be the caption height + inner table height + space between them
- aDesiredSize.height = aReflowState.y;
- }
- // Return our desired rect
- aDesiredSize.width = aReflowState.innerTableMaxSize.width;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- if (PR_TRUE==gsDebugIR) printf("TOF IR: aDS.width=%d, aDS.height=%d\n",
- aDesiredSize.width, aDesiredSize.height);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: innerRect=%d %d %d %d\n", innerRect.x, innerRect.y,
+ innerRect.width, innerRect.height);
+
+ aReflowState.innerTableMaxSize.width = innerSize.width;
return rv;
}
@@ -569,8 +640,10 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
// make aCaptionFrame this table's caption
mCaptionFrame = aCaptionFrame;
+ mInnerTableFrame->SetNextSibling(mCaptionFrame);
// reflow the caption frame, getting it's MES
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: initial-reflowing caption\n");
nsSize maxElementSize;
nsHTMLReflowMetrics captionSize(&maxElementSize);
nsHTMLReflowState captionReflowState(mCaptionFrame, aReflowState.reflowState,
@@ -581,87 +654,53 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
if (NS_OK == mCaptionFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow))
{ // initial reflow of the caption
htmlReflow->WillReflow(aPresContext);
- htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ rv = htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width =%d, height = %d, minWidth=%d\n",
+ rv, captionSize.width, captionSize.height, maxElementSize.width);
mMinCaptionWidth = maxElementSize.width;
// get the caption's alignment
const nsStyleText* captionTextStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- if ((captionTextStyle->mVerticalAlign.GetUnit()!=eStyleUnit_Enumerated) || // default is "top"
+ if (PR_TRUE || // XXX: this is a hack because we don't support left|right captions yet
+ (captionTextStyle->mVerticalAlign.GetUnit()!=eStyleUnit_Enumerated) || // default is "top"
((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
((captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_TOP) ||
(captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))))
{
// XXX: caption align = left|right ignored here!
- // if the caption's MES > TMW, reflow the inner table
- nscoord tableMaxWidth = ((nsTableFrame *)mInnerTableFrame)->GetMaxTableWidth();
+ // if the caption's MES > table width, reflow the inner table
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
- if ((oldCaptionMES != mMinCaptionWidth) && (mMinCaptionWidth > tableMaxWidth))
+ if ((oldCaptionMES != mMinCaptionWidth) && (mMinCaptionWidth > mRect.width))
{
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: resize-reflowing inner table\n");
nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
- nsSize(mMinCaptionWidth, aReflowState.reflowState.maxSize.height));
+ nsSize(mMinCaptionWidth, aReflowState.reflowState.maxSize.height),
+ eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: inner table reflow returned %d with width =%d, height = %d\n",
+ rv, innerSize.width, innerSize.height);
}
else
{ // set innerSize as if the inner table were reflowed
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping reflow of inner table\n");
innerSize.height = mRect.height;
innerSize.width = mRect.width;
}
// set maxElementSize width if requested
- if (nsnull != aDesiredSize.maxElementSize) {
- if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
+ if (nsnull != aDesiredSize.maxElementSize)
+ {
+ ((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
+ if (mMinCaptionWidth > aDesiredSize.maxElementSize->width)
+ {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
}
- // find where to place the caption
- nsMargin captionMargin;
- const nsStyleSpacing* spacing;
- mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
- spacing->CalcMarginFor(mCaptionFrame, captionMargin);
- // Compute the caption's y-origin
- nscoord captionY = captionMargin.top;
- const nsStyleText* captionTextStyle;
- mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
- (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
- {
- captionY += innerSize.height;
- }
- // Place the caption
- nsRect captionRect(captionMargin.left, captionY, 0, 0);
- captionRect.SizeTo(captionSize.width, captionSize.height);
- mCaptionFrame->SetRect(captionRect);
- // Place the inner table
- nscoord innerY;
- if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
- (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
-
- { // bottom caption
- innerY = 0;
- aReflowState.y = captionRect.YMost() + captionMargin.bottom;
- }
- else
- { // top caption
- innerY = captionRect.YMost() + captionMargin.bottom;
- aReflowState.y = innerY + innerSize.height;
- }
- nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
- mInnerTableFrame->SetRect(innerRect);
- /* if we're incomplete, take up all the remaining height so we don't waste time
- * trying to lay out in a slot that we know isn't tall enough to fit our minimum.
- * otherwise, we're as tall as our kids want us to be */
- if (NS_FRAME_IS_NOT_COMPLETE(aStatus))
- aDesiredSize.height = aReflowState.reflowState.maxSize.height;
- else
- aDesiredSize.height = aReflowState.y;
- // Return our desired rect
- aDesiredSize.width = aReflowState.innerTableMaxSize.width;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- }
- else
- {
- rv = NS_ERROR_NOT_IMPLEMENTED;
- if (PR_TRUE==gsDebugIR) printf("TOF IR: left|right caption not implemented.\n");
+
+ rv = SizeAndPlaceChildren(nsSize (innerSize.width, innerSize.height),
+ nsSize (captionSize.width, captionSize.height),
+ aReflowState);
}
}
return rv;
@@ -679,20 +718,34 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
// get the caption's alignment
const nsStyleText* captionTextStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
- // if the caption's MES > TMW, reflow the inner table minus the MES
- nscoord tableMaxWidth = ((nsTableFrame *)mInnerTableFrame)->GetMaxTableWidth();
+ // if the caption's MES > table width, reflow the inner table minus the MES
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
nscoord oldMinCaptionWidth = mMinCaptionWidth;
// set the cached min caption width to 0 here, so it can't effect inner table reflow
mMinCaptionWidth = 0;
mCaptionFrame=nsnull;
- if (oldMinCaptionWidth > tableMaxWidth)
+ mInnerTableFrame->SetNextSibling(nsnull);
+ if (oldMinCaptionWidth > mRect.width)
{ // the old caption width had an effect on the inner table width, so reflow the inner table
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: reflowing inner table\n");
nsHTMLReflowState innerReflowState(mInnerTableFrame, aReflowState.reflowState,
nsSize(aReflowState.reflowState.maxSize.width,
aReflowState.reflowState.maxSize.height));
// ReflowChild sets MES
- ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ if (NS_FAILED(rv))
+ return rv;
+ // set the output state
+ aReflowState.innerTableMaxSize.width = innerSize.width;
+ aReflowState.y = innerSize.height;
+ }
+ else
+ {
+ if (PR_TRUE==gsDebugIR) printf("TOF IR: skipping reflow of inner table\n");
+ nsRect innerRect;
+ mInnerTableFrame->GetRect(innerRect);
+ aReflowState.innerTableMaxSize.width = innerRect.width;
+ aReflowState.y = innerRect.height;
}
// if the caption was a top caption, move the inner table to the correct offset
if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
@@ -700,11 +753,6 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
{
mInnerTableFrame->MoveTo(0,0);
}
- // Return our desired rect
- aDesiredSize.width = innerSize.width; //aReflowState.innerTableMaxSize.width;
- aDesiredSize.height = innerSize.height;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
}
else
rv = NS_ERROR_ILLEGAL_VALUE;
@@ -712,6 +760,65 @@ nsresult nsTableOuterFrame::IR_CaptionDeleted(nsIPresContext& aPresContex
return rv;
}
+PRBool nsTableOuterFrame::IR_CaptionChangedAxis(const nsStyleText* aOldStyle,
+ const nsStyleText* aNewStyle) const
+{
+ PRBool result = PR_FALSE;
+ //XXX: write me to support left|right captions!
+ return result;
+}
+
+nsresult nsTableOuterFrame::SizeAndPlaceChildren(const nsSize & aInnerSize,
+ const nsSize & aCaptionSize,
+ OuterTableReflowState& aReflowState)
+{
+ if (PR_TRUE==gsDebugIR) printf(" TOF IR: SizeAndPlaceChildren\n");
+ nsresult rv = NS_OK;
+ // find where to place the caption
+ nsMargin captionMargin;
+ const nsStyleSpacing* spacing;
+ mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)spacing);
+ spacing->CalcMarginFor(mCaptionFrame, captionMargin);
+ // Compute the caption's y-origin
+ nscoord captionY = captionMargin.top;
+ const nsStyleText* captionTextStyle;
+ mCaptionFrame->GetStyleData(eStyleStruct_Text, ((nsStyleStruct *&)captionTextStyle));
+ if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
+ (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
+ {
+ captionY += aInnerSize.height;
+ }
+ // Place the caption
+ nsRect captionRect(captionMargin.left, captionY, 0, 0);
+ captionRect.SizeTo(aCaptionSize.width, aCaptionSize.height);
+ mCaptionFrame->SetRect(captionRect);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: captionRect=%d %d %d %d\n", captionRect.x, captionRect.y,
+ captionRect.width, captionRect.height);
+
+ // Place the inner table
+ nscoord innerY;
+ if ((captionTextStyle->mVerticalAlign.GetUnit()==eStyleUnit_Enumerated) &&
+ (captionTextStyle->mVerticalAlign.GetIntValue()==NS_STYLE_VERTICAL_ALIGN_BOTTOM))
+
+ { // bottom caption
+ innerY = 0;
+ aReflowState.y = captionRect.YMost() + captionMargin.bottom;
+ }
+ else
+ { // top caption
+ innerY = captionRect.YMost() + captionMargin.bottom;
+ aReflowState.y = innerY + aInnerSize.height;
+ }
+ nsRect innerRect(0, innerY, aInnerSize.width, aInnerSize.height);
+ mInnerTableFrame->SetRect(innerRect);
+ if (PR_TRUE==gsDebugIR)
+ printf(" TOF IR: innerRect=%d %d %d %d\n", innerRect.x, innerRect.y,
+ innerRect.width, innerRect.height);
+ aReflowState.innerTableMaxSize.width = aInnerSize.width;
+ return rv;
+}
+
/**
* Called by the Reflow() member function to compute the table width
*/
@@ -787,6 +894,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ nsresult rv = NS_OK;
if (PR_TRUE==gsDebug)
printf("%p: nsTableOuterFrame::Reflow : maxSize=%d,%d\n",
this, aReflowState.maxSize.width, aReflowState.maxSize.height);
@@ -808,11 +916,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Initialize our local reflow state
OuterTableReflowState state(aPresContext, aReflowState);
if (eReflowReason_Incremental == aReflowState.reason) {
- IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
-
- // Return our desired rect
- aDesiredSize.width = state.innerTableMaxSize.width;
-
+ rv = IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
} else {
if (eReflowReason_Initial == aReflowState.reason) {
//KIPP/TROY: uncomment the following line for your own testing, do not check it in
@@ -833,7 +937,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
if (NS_OK == mCaptionFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->WillReflow(aPresContext);
- htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
+ rv = htmlReflow->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mMinCaptionWidth = maxElementSize.width;
}
}
@@ -858,7 +962,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
nsSize(tableWidth, aReflowState.maxSize.height));
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
- ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
+ rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus);
// Table's max element size is the MAX of the caption's max element size
// and the inner table's max element size...
@@ -946,7 +1050,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
- if (gsDebug==PR_TRUE)
+ if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
{
if (nsnull!=aDesiredSize.maxElementSize)
printf("%p: Outer frame Reflow complete, returning %s with aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n",
@@ -965,7 +1069,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
endTime-startTime, this);/* XXX need to use LL_* macros! */
}
- return NS_OK;
+ return rv;
}
// Position and size aKidFrame and update our reflow state. The origin of
diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h
index ed5bd1231f7..cd563bc0970 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.h
+++ b/mozilla/layout/tables/nsTableOuterFrame.h
@@ -22,6 +22,7 @@
#include "nsContainerFrame.h"
struct OuterTableReflowState;
+struct nsStyleText;
/**
* main frame for an nsTable content object,
@@ -168,6 +169,13 @@ protected:
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
+ PRBool IR_CaptionChangedAxis(const nsStyleText* aOldStyle,
+ const nsStyleText* aNewStyle) const;
+
+ nsresult SizeAndPlaceChildren(const nsSize & aInnerSize,
+ const nsSize & aCaptionSize,
+ OuterTableReflowState& aReflowState);
+
nsresult AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,