diff --git a/mozilla/content/html/content/src/nsHTMLTableElement.cpp b/mozilla/content/html/content/src/nsHTMLTableElement.cpp
index 4b45e6f5dd1..35b74089c2a 100644
--- a/mozilla/content/html/content/src/nsHTMLTableElement.cpp
+++ b/mozilla/content/html/content/src/nsHTMLTableElement.cpp
@@ -1117,11 +1117,17 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes,
aContext->GetMutableStyleData(eStyleStruct_Position);
switch (value.GetUnit()) {
case eHTMLUnit_Percent:
- position->mWidth.SetPercentValue(value.GetPercentValue());
+ // 0 width remains default auto
+ //if (value.GetPercentValue() > 0.0f) {
+ position->mWidth.SetPercentValue(value.GetPercentValue());
+ //}
break;
case eHTMLUnit_Pixel:
- position->mWidth.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t));
+ // 0 width remains default auto
+ //if (value.GetPixelValue() > 0) {
+ position->mWidth.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t));
+ //}
break;
default:
break;
diff --git a/mozilla/content/shared/public/nsLayoutAtomList.h b/mozilla/content/shared/public/nsLayoutAtomList.h
index c584e5b8552..6c416edadba 100644
--- a/mozilla/content/shared/public/nsLayoutAtomList.h
+++ b/mozilla/content/shared/public/nsLayoutAtomList.h
@@ -59,6 +59,7 @@ LAYOUT_ATOM(xmlnsNameSpace, "xmlns")
// Alphabetical list of frame additional child list names
LAYOUT_ATOM(absoluteList, "Absolute-list")
LAYOUT_ATOM(bulletList, "Bullet-list")
+LAYOUT_ATOM(captionList, "Caption-list")
LAYOUT_ATOM(colGroupList, "ColGroup-list")
LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
LAYOUT_ATOM(fixedList, "Fixed-list")
@@ -96,6 +97,7 @@ LAYOUT_ATOM(placeholderFrame, "PlaceholderFrame")
LAYOUT_ATOM(positionedInlineFrame, "PositionedInlineFrame")
LAYOUT_ATOM(rootFrame, "RootFrame")
LAYOUT_ATOM(scrollFrame, "ScrollFrame")
+LAYOUT_ATOM(tableCaptionFrame, "TableCaptionFrame")
LAYOUT_ATOM(tableCellFrame, "TableCellFrame")
LAYOUT_ATOM(tableColFrame, "TableColFrame")
LAYOUT_ATOM(tableColGroupFrame, "TableColGroupFrame")
diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp
index 65f9d146b1c..6c8021bc224 100644
--- a/mozilla/layout/base/nsCSSFrameConstructor.cpp
+++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp
@@ -518,6 +518,19 @@ nsMathMLmtableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame)
// -----------------------------------------------------------
+// return the child list that aFrame belongs on. does not ADDREF
+nsIAtom* GetChildListFor(const nsIFrame* aFrame)
+{
+ nsIAtom* childList = nsnull;
+ nsIAtom* frameType;
+ aFrame->GetFrameType(&frameType);
+ if (nsLayoutAtoms::tableCaptionFrame == frameType) {
+ childList = nsLayoutAtoms::captionList;
+ }
+ NS_IF_RELEASE(frameType);
+ return childList;
+}
+
nsCSSFrameConstructor::nsCSSFrameConstructor(void)
: nsIStyleFrameConstruction(),
mDocument(nsnull),
@@ -1067,15 +1080,6 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
#endif
// Create the inner table frame
aTableCreator.CreateTableFrame(&innerFrame);
-
- // This gets reset later, since there may also be a caption.
- // It allows descendants to get at the inner frame before that
- // XXX This is very wrong. You cannot call SetInitialChildList() more
- // than once (see the nsIFrame header file). Either call it once only,
- // _or_ move the caption out into a separate named child list...
- // XXX The other things that's wrong here is that the calls to
- // SetInitialChildList() are bottom-up, and the order is wrong...
- aNewFrame->SetInitialChildList(aPresContext, nsnull, innerFrame);
childList = innerFrame;
InitAndRestoreFrame(aPresContext, aState, aContent,
@@ -1164,11 +1168,14 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
}
}
- // Set the inner table frame's list of initial child frames
+ // Set the inner table frame's initial primary list
innerFrame->SetInitialChildList(aPresContext, nsnull, innerChildList);
- // Set the anonymous table outer frame's initial child list
+ // Set the outer table frame's primary and option lists
aNewFrame->SetInitialChildList(aPresContext, nsnull, childList);
+ if (captionFrame) {
+ aNewFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList, captionFrame);
+ }
return rv;
}
@@ -1287,7 +1294,7 @@ nsCSSFrameConstructor::ConstructAnonymousTableFrame(nsIPresShell* aPresSh
InitAndRestoreFrame(aPresContext, aState, aContent,
aOuterFrame, innerStyleContext, nsnull, aInnerFrame);
- //XXX duplicated call here
+ //XXX when bug 2479 is fixed this may be a duplicate call
aOuterFrame->SetInitialChildList(aPresContext, nsnull, aInnerFrame);
if (cellIsParent) {
@@ -1315,28 +1322,17 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
if (NS_FAILED(rv)) return rv;
const nsStyleDisplay* parentDisplay = GetDisplay(aParentFrame);
- nsIFrame* innerFrame;
+ nsIFrame* outerFrame = aParentFrame;
if (NS_STYLE_DISPLAY_TABLE == parentDisplay->mDisplay) { // parent is an outer table
- // determine the inner table frame, it is either aParentFrame or its first child
- nsIFrame* parFrame = aParentFrame;
- aParentFrame->FirstChild(aPresContext, nsnull, &innerFrame);
- const nsStyleDisplay* innerDisplay;
- innerFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)innerDisplay);
- if (NS_STYLE_DISPLAY_TABLE != innerDisplay->mDisplay) {
- innerFrame = aParentFrame;
- innerFrame->GetParent(&parFrame);
- }
-
InitAndRestoreFrame(aPresContext, aState, aContent,
- parFrame, aStyleContext, nsnull, aNewCaptionFrame);
+ aParentFrame, aStyleContext, nsnull, aNewCaptionFrame);
- innerFrame->SetNextSibling(aNewCaptionFrame);
- // the caller is responsible for calling SetInitialChildList on the outer, inner frames
+ // the caller is responsible for calling SetInitialChildList
aNewTopFrame = aNewCaptionFrame;
} else { // parent is not a table, need to create a new table
//NS_WARNING("a non table contains a table caption child. \n");
- nsIFrame* outerFrame;
+ nsIFrame* innerFrame;
ConstructAnonymousTableFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
aNewTopFrame, outerFrame, innerFrame, aTableCreator);
nsCOMPtr outerStyleContext;
@@ -1346,9 +1342,6 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
PR_FALSE, getter_AddRefs(adjStyleContext));
InitAndRestoreFrame(aPresContext, aState, aContent,
outerFrame, adjStyleContext, nsnull, aNewCaptionFrame);
- innerFrame->SetNextSibling(aNewCaptionFrame);
- //XXX duplicated call here
- outerFrame->SetInitialChildList(aPresContext, nsnull, innerFrame);
}
// The caption frame is a floater container
@@ -1372,6 +1365,11 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
aState.mFloatedItems.childList);
}
+ if (outerFrame) {
+ outerFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList,
+ aNewCaptionFrame);
+ }
+
return rv;
}
@@ -1601,13 +1599,13 @@ nsCSSFrameConstructor::ConstructTableRowFrame(nsIPresShell* aPresShell,
contentDisplayIsRow, aNewRowFrame, aTableCreator);
if (NS_FAILED(rv)) return rv;
+ //XXX when bug 2479 is fixed this may be a duplicate call
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewRowFrame);
if (contentDisplayIsRow) { // called from above
// set the primary frame to avoid getting the anonymous row group frame
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewRowFrame);
}
- groupFrame->SetInitialChildList(aPresContext, nsnull, aNewRowFrame);
if (contentDisplayIsRow) { // called from above
TableProcessTableList(aPresContext, *toDo);
}
@@ -1680,6 +1678,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
styleContext, aNewColFrame, aTableCreator);
if (NS_FAILED(rv)) return rv;
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewColFrame);
+ //XXX when bug 2479 is fixed this may be a duplicate call
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewColFrame);
// if an anoymous table got created, then set its initial child list
@@ -1776,6 +1775,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShell,
styleContext, aNewCellFrame, aNewCellBodyFrame,
aTableCreator, aProcessChildren);
if (NS_FAILED(rv)) return rv;
+ //XXX when bug 2479 is fixed this may be a duplicate call
rowFrame->SetInitialChildList(aPresContext, nsnull, aNewCellFrame);
TableProcessTableList(aPresContext, toDo);
}
@@ -5755,6 +5755,8 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
aFrameList);
}
+ nsresult rv = NS_OK;
+
// a col group or col appended to a table may result in an insert rather than an append
nsIAtom* parentType;
aParentFrame->GetFrameType(&parentType);
@@ -5763,30 +5765,45 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
nsIAtom* childType;
aFrameList->GetFrameType(&childType);
if (nsLayoutAtoms::tableColFrame == childType) {
+ // table column
nsIFrame* parentFrame = aParentFrame;
aFrameList->GetParent(&parentFrame);
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
- nsLayoutAtoms::colGroupList, aFrameList);
+ NS_RELEASE(childType);
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
+ nsLayoutAtoms::colGroupList, aFrameList);
}
else if (nsLayoutAtoms::tableColGroupFrame == childType) {
+ // table col group
nsIFrame* prevSibling;
PRBool doAppend = nsTableColGroupFrame::GetLastRealColGroup(tableFrame, &prevSibling);
if (doAppend) {
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
- nsLayoutAtoms::colGroupList, aFrameList);
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::colGroupList, aFrameList);
}
else {
- return aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
- nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
+ rv = aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
}
}
+ else if (nsLayoutAtoms::tableCaptionFrame == childType) {
+ // table caption
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::captionList, aFrameList);
+ }
+ else {
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsnull, aFrameList);
+ }
NS_IF_RELEASE(childType);
}
+ else {
+ // Append the frames to the end of the parent's child list
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsnull, aFrameList);
+ }
NS_IF_RELEASE(parentType);
- // Append the frames to the end of the parent's child list
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
- nsnull, aFrameList);
+ return rv;
}
static nsIFrame*
@@ -6529,10 +6546,11 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
prevSibling = firstChild;
}
}
-
+ // check for a table caption which goes on an additional child list
+ nsIAtom* childList = GetChildListFor(newFrame);
rv = state.mFrameManager->InsertFrames(aPresContext, *shell,
parentFrame,
- nsnull, prevSibling,
+ childList, prevSibling,
newFrame);
}
@@ -7021,8 +7039,9 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} else {
// Notify the parent frame that it should delete the frame
+ nsIAtom* childList = GetChildListFor(childFrame);
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
- nsnull, childFrame);
+ childList, childFrame);
}
}
diff --git a/mozilla/layout/base/nsLayoutAtomList.h b/mozilla/layout/base/nsLayoutAtomList.h
index c584e5b8552..6c416edadba 100644
--- a/mozilla/layout/base/nsLayoutAtomList.h
+++ b/mozilla/layout/base/nsLayoutAtomList.h
@@ -59,6 +59,7 @@ LAYOUT_ATOM(xmlnsNameSpace, "xmlns")
// Alphabetical list of frame additional child list names
LAYOUT_ATOM(absoluteList, "Absolute-list")
LAYOUT_ATOM(bulletList, "Bullet-list")
+LAYOUT_ATOM(captionList, "Caption-list")
LAYOUT_ATOM(colGroupList, "ColGroup-list")
LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
LAYOUT_ATOM(fixedList, "Fixed-list")
@@ -96,6 +97,7 @@ LAYOUT_ATOM(placeholderFrame, "PlaceholderFrame")
LAYOUT_ATOM(positionedInlineFrame, "PositionedInlineFrame")
LAYOUT_ATOM(rootFrame, "RootFrame")
LAYOUT_ATOM(scrollFrame, "ScrollFrame")
+LAYOUT_ATOM(tableCaptionFrame, "TableCaptionFrame")
LAYOUT_ATOM(tableCellFrame, "TableCellFrame")
LAYOUT_ATOM(tableColFrame, "TableColFrame")
LAYOUT_ATOM(tableColGroupFrame, "TableColGroupFrame")
diff --git a/mozilla/layout/base/public/nsLayoutAtomList.h b/mozilla/layout/base/public/nsLayoutAtomList.h
index c584e5b8552..6c416edadba 100644
--- a/mozilla/layout/base/public/nsLayoutAtomList.h
+++ b/mozilla/layout/base/public/nsLayoutAtomList.h
@@ -59,6 +59,7 @@ LAYOUT_ATOM(xmlnsNameSpace, "xmlns")
// Alphabetical list of frame additional child list names
LAYOUT_ATOM(absoluteList, "Absolute-list")
LAYOUT_ATOM(bulletList, "Bullet-list")
+LAYOUT_ATOM(captionList, "Caption-list")
LAYOUT_ATOM(colGroupList, "ColGroup-list")
LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
LAYOUT_ATOM(fixedList, "Fixed-list")
@@ -96,6 +97,7 @@ LAYOUT_ATOM(placeholderFrame, "PlaceholderFrame")
LAYOUT_ATOM(positionedInlineFrame, "PositionedInlineFrame")
LAYOUT_ATOM(rootFrame, "RootFrame")
LAYOUT_ATOM(scrollFrame, "ScrollFrame")
+LAYOUT_ATOM(tableCaptionFrame, "TableCaptionFrame")
LAYOUT_ATOM(tableCellFrame, "TableCellFrame")
LAYOUT_ATOM(tableColFrame, "TableColFrame")
LAYOUT_ATOM(tableColGroupFrame, "TableColGroupFrame")
diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h
index 7e631aca51e..dd31d3f80a8 100644
--- a/mozilla/layout/generic/nsHTMLParts.h
+++ b/mozilla/layout/generic/nsHTMLParts.h
@@ -280,9 +280,6 @@ extern nsresult NS_NewAreaFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
inline nsresult NS_NewTableCellInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) {
return NS_NewBlockFrame(aPresShell, aNewFrame, NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
}
-inline nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) {
- return NS_NewBlockFrame(aPresShell, aNewFrame, NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
-}
// This type of AreaFrame is the document root, a margin root, and the
// initial containing block for absolutely positioned elements
@@ -359,6 +356,8 @@ extern nsresult NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsIFrame**
// Table frame factories
extern nsresult NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
+extern nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
+
extern nsresult NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableRowFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
diff --git a/mozilla/layout/html/base/src/nsHTMLParts.h b/mozilla/layout/html/base/src/nsHTMLParts.h
index 7e631aca51e..dd31d3f80a8 100644
--- a/mozilla/layout/html/base/src/nsHTMLParts.h
+++ b/mozilla/layout/html/base/src/nsHTMLParts.h
@@ -280,9 +280,6 @@ extern nsresult NS_NewAreaFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
inline nsresult NS_NewTableCellInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) {
return NS_NewBlockFrame(aPresShell, aNewFrame, NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
}
-inline nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) {
- return NS_NewBlockFrame(aPresShell, aNewFrame, NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
-}
// This type of AreaFrame is the document root, a margin root, and the
// initial containing block for absolutely positioned elements
@@ -359,6 +356,8 @@ extern nsresult NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsIFrame**
// Table frame factories
extern nsresult NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
+extern nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
+
extern nsresult NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
extern nsresult NS_NewTableRowFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
diff --git a/mozilla/layout/html/content/src/nsHTMLTableElement.cpp b/mozilla/layout/html/content/src/nsHTMLTableElement.cpp
index 4b45e6f5dd1..35b74089c2a 100644
--- a/mozilla/layout/html/content/src/nsHTMLTableElement.cpp
+++ b/mozilla/layout/html/content/src/nsHTMLTableElement.cpp
@@ -1117,11 +1117,17 @@ MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes,
aContext->GetMutableStyleData(eStyleStruct_Position);
switch (value.GetUnit()) {
case eHTMLUnit_Percent:
- position->mWidth.SetPercentValue(value.GetPercentValue());
+ // 0 width remains default auto
+ //if (value.GetPercentValue() > 0.0f) {
+ position->mWidth.SetPercentValue(value.GetPercentValue());
+ //}
break;
case eHTMLUnit_Pixel:
- position->mWidth.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t));
+ // 0 width remains default auto
+ //if (value.GetPixelValue() > 0) {
+ position->mWidth.SetCoordValue(NSIntPixelsToTwips(value.GetPixelValue(), sp2t));
+ //}
break;
default:
break;
diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp
index 65f9d146b1c..6c8021bc224 100644
--- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp
+++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp
@@ -518,6 +518,19 @@ nsMathMLmtableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame)
// -----------------------------------------------------------
+// return the child list that aFrame belongs on. does not ADDREF
+nsIAtom* GetChildListFor(const nsIFrame* aFrame)
+{
+ nsIAtom* childList = nsnull;
+ nsIAtom* frameType;
+ aFrame->GetFrameType(&frameType);
+ if (nsLayoutAtoms::tableCaptionFrame == frameType) {
+ childList = nsLayoutAtoms::captionList;
+ }
+ NS_IF_RELEASE(frameType);
+ return childList;
+}
+
nsCSSFrameConstructor::nsCSSFrameConstructor(void)
: nsIStyleFrameConstruction(),
mDocument(nsnull),
@@ -1067,15 +1080,6 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
#endif
// Create the inner table frame
aTableCreator.CreateTableFrame(&innerFrame);
-
- // This gets reset later, since there may also be a caption.
- // It allows descendants to get at the inner frame before that
- // XXX This is very wrong. You cannot call SetInitialChildList() more
- // than once (see the nsIFrame header file). Either call it once only,
- // _or_ move the caption out into a separate named child list...
- // XXX The other things that's wrong here is that the calls to
- // SetInitialChildList() are bottom-up, and the order is wrong...
- aNewFrame->SetInitialChildList(aPresContext, nsnull, innerFrame);
childList = innerFrame;
InitAndRestoreFrame(aPresContext, aState, aContent,
@@ -1164,11 +1168,14 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
}
}
- // Set the inner table frame's list of initial child frames
+ // Set the inner table frame's initial primary list
innerFrame->SetInitialChildList(aPresContext, nsnull, innerChildList);
- // Set the anonymous table outer frame's initial child list
+ // Set the outer table frame's primary and option lists
aNewFrame->SetInitialChildList(aPresContext, nsnull, childList);
+ if (captionFrame) {
+ aNewFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList, captionFrame);
+ }
return rv;
}
@@ -1287,7 +1294,7 @@ nsCSSFrameConstructor::ConstructAnonymousTableFrame(nsIPresShell* aPresSh
InitAndRestoreFrame(aPresContext, aState, aContent,
aOuterFrame, innerStyleContext, nsnull, aInnerFrame);
- //XXX duplicated call here
+ //XXX when bug 2479 is fixed this may be a duplicate call
aOuterFrame->SetInitialChildList(aPresContext, nsnull, aInnerFrame);
if (cellIsParent) {
@@ -1315,28 +1322,17 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
if (NS_FAILED(rv)) return rv;
const nsStyleDisplay* parentDisplay = GetDisplay(aParentFrame);
- nsIFrame* innerFrame;
+ nsIFrame* outerFrame = aParentFrame;
if (NS_STYLE_DISPLAY_TABLE == parentDisplay->mDisplay) { // parent is an outer table
- // determine the inner table frame, it is either aParentFrame or its first child
- nsIFrame* parFrame = aParentFrame;
- aParentFrame->FirstChild(aPresContext, nsnull, &innerFrame);
- const nsStyleDisplay* innerDisplay;
- innerFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)innerDisplay);
- if (NS_STYLE_DISPLAY_TABLE != innerDisplay->mDisplay) {
- innerFrame = aParentFrame;
- innerFrame->GetParent(&parFrame);
- }
-
InitAndRestoreFrame(aPresContext, aState, aContent,
- parFrame, aStyleContext, nsnull, aNewCaptionFrame);
+ aParentFrame, aStyleContext, nsnull, aNewCaptionFrame);
- innerFrame->SetNextSibling(aNewCaptionFrame);
- // the caller is responsible for calling SetInitialChildList on the outer, inner frames
+ // the caller is responsible for calling SetInitialChildList
aNewTopFrame = aNewCaptionFrame;
} else { // parent is not a table, need to create a new table
//NS_WARNING("a non table contains a table caption child. \n");
- nsIFrame* outerFrame;
+ nsIFrame* innerFrame;
ConstructAnonymousTableFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
aNewTopFrame, outerFrame, innerFrame, aTableCreator);
nsCOMPtr outerStyleContext;
@@ -1346,9 +1342,6 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
PR_FALSE, getter_AddRefs(adjStyleContext));
InitAndRestoreFrame(aPresContext, aState, aContent,
outerFrame, adjStyleContext, nsnull, aNewCaptionFrame);
- innerFrame->SetNextSibling(aNewCaptionFrame);
- //XXX duplicated call here
- outerFrame->SetInitialChildList(aPresContext, nsnull, innerFrame);
}
// The caption frame is a floater container
@@ -1372,6 +1365,11 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
aState.mFloatedItems.childList);
}
+ if (outerFrame) {
+ outerFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList,
+ aNewCaptionFrame);
+ }
+
return rv;
}
@@ -1601,13 +1599,13 @@ nsCSSFrameConstructor::ConstructTableRowFrame(nsIPresShell* aPresShell,
contentDisplayIsRow, aNewRowFrame, aTableCreator);
if (NS_FAILED(rv)) return rv;
+ //XXX when bug 2479 is fixed this may be a duplicate call
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewRowFrame);
if (contentDisplayIsRow) { // called from above
// set the primary frame to avoid getting the anonymous row group frame
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewRowFrame);
}
- groupFrame->SetInitialChildList(aPresContext, nsnull, aNewRowFrame);
if (contentDisplayIsRow) { // called from above
TableProcessTableList(aPresContext, *toDo);
}
@@ -1680,6 +1678,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
styleContext, aNewColFrame, aTableCreator);
if (NS_FAILED(rv)) return rv;
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewColFrame);
+ //XXX when bug 2479 is fixed this may be a duplicate call
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewColFrame);
// if an anoymous table got created, then set its initial child list
@@ -1776,6 +1775,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShell,
styleContext, aNewCellFrame, aNewCellBodyFrame,
aTableCreator, aProcessChildren);
if (NS_FAILED(rv)) return rv;
+ //XXX when bug 2479 is fixed this may be a duplicate call
rowFrame->SetInitialChildList(aPresContext, nsnull, aNewCellFrame);
TableProcessTableList(aPresContext, toDo);
}
@@ -5755,6 +5755,8 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
aFrameList);
}
+ nsresult rv = NS_OK;
+
// a col group or col appended to a table may result in an insert rather than an append
nsIAtom* parentType;
aParentFrame->GetFrameType(&parentType);
@@ -5763,30 +5765,45 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
nsIAtom* childType;
aFrameList->GetFrameType(&childType);
if (nsLayoutAtoms::tableColFrame == childType) {
+ // table column
nsIFrame* parentFrame = aParentFrame;
aFrameList->GetParent(&parentFrame);
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
- nsLayoutAtoms::colGroupList, aFrameList);
+ NS_RELEASE(childType);
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
+ nsLayoutAtoms::colGroupList, aFrameList);
}
else if (nsLayoutAtoms::tableColGroupFrame == childType) {
+ // table col group
nsIFrame* prevSibling;
PRBool doAppend = nsTableColGroupFrame::GetLastRealColGroup(tableFrame, &prevSibling);
if (doAppend) {
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
- nsLayoutAtoms::colGroupList, aFrameList);
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::colGroupList, aFrameList);
}
else {
- return aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
- nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
+ rv = aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
}
}
+ else if (nsLayoutAtoms::tableCaptionFrame == childType) {
+ // table caption
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsLayoutAtoms::captionList, aFrameList);
+ }
+ else {
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsnull, aFrameList);
+ }
NS_IF_RELEASE(childType);
}
+ else {
+ // Append the frames to the end of the parent's child list
+ rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
+ nsnull, aFrameList);
+ }
NS_IF_RELEASE(parentType);
- // Append the frames to the end of the parent's child list
- return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
- nsnull, aFrameList);
+ return rv;
}
static nsIFrame*
@@ -6529,10 +6546,11 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
prevSibling = firstChild;
}
}
-
+ // check for a table caption which goes on an additional child list
+ nsIAtom* childList = GetChildListFor(newFrame);
rv = state.mFrameManager->InsertFrames(aPresContext, *shell,
parentFrame,
- nsnull, prevSibling,
+ childList, prevSibling,
newFrame);
}
@@ -7021,8 +7039,9 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} else {
// Notify the parent frame that it should delete the frame
+ nsIAtom* childList = GetChildListFor(childFrame);
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
- nsnull, childFrame);
+ childList, childFrame);
}
}
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
index ab088eeafe6..eeeac9c2ba3 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
@@ -691,22 +691,20 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
DebugCheckChildSize(firstKid, kidSize, availSize, (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth));
#endif
- PRBool useInsets = PR_TRUE;
// 0 dimensioned cells need to be treated specially in Standard/NavQuirks mode
// see testcase "emptyCells.html"
- if (NS_UNCONSTRAINEDSIZE == kidReflowState.availableWidth) {
- if ((0 == kidSize.width) || (0 == kidSize.height)) {
- //if ((0 == kidSize.width) && (0 == kidSize.height)) { // XXX why was this &&
- SetContentEmpty(PR_TRUE);
- useInsets = PR_FALSE;
+ if ((0 == kidSize.width) || (0 == kidSize.height)) { // XXX why was this &&
+ SetContentEmpty(PR_TRUE);
+ if (NS_UNCONSTRAINEDSIZE == kidReflowState.availableWidth) {
// need to reduce the insets by border if the cell is empty
leftInset -= border.left;
rightInset -= border.right;
topInset -= border.top;
bottomInset -= border.bottom;
}
- else
- SetContentEmpty(PR_FALSE);
+ }
+ else {
+ SetContentEmpty(PR_FALSE);
}
const nsStylePosition* pos;
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index a280179bd91..83575485286 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -58,6 +58,7 @@
#include "nsIDOMHTMLBodyElement.h"
#include "nsISizeOfHandler.h"
#include "nsIScrollableFrame.h"
+#include "nsHTMLReflowCommand.h"
NS_DEF_PTR(nsIStyleContext);
NS_DEF_PTR(nsIContent);
@@ -84,6 +85,8 @@ PRBool nsDebugTable::gRflRow = PR_TRUE;
PRBool nsDebugTable::gRflCell = PR_TRUE;
PRBool nsDebugTable::gRflArea = PR_TRUE;
#endif
+static PRInt32 gRflCount = 0;
+
/* ----------- InnerTableReflowState ---------- */
struct InnerTableReflowState {
@@ -4678,7 +4681,11 @@ void nsTableFrame::DebugReflow(char* aMessage,
printf("rea=%d av=(%s,%s) ", aState->reason, width, height);
PrettyUC(aState->mComputedWidth, width);
PrettyUC(aState->mComputedHeight, height);
- printf("comp=(%s,%s) \n", width, height);
+ printf("comp=(%s,%s) count=%d \n", width, height, gRflCount);
+ gRflCount++;
+ //if (32 == gRflCount) {
+ // NS_ASSERTION(PR_FALSE, "stop");
+ //}
}
if (aMetrics) {
if (aState) {
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
index d8082427efb..abfe42508a5 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
@@ -36,6 +36,42 @@
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
+#define NS_TABLE_FRAME_CAPTION_LIST_INDEX 0
+
+// caption frame
+nsTableCaptionFrame::nsTableCaptionFrame()
+{
+ // shrink wrap
+ SetFlags(NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
+}
+
+NS_IMETHODIMP
+nsTableCaptionFrame::GetFrameType(nsIAtom** aType) const
+{
+ NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
+ *aType = nsLayoutAtoms::tableCaptionFrame;
+ NS_ADDREF(*aType);
+ return NS_OK;
+}
+
+nsresult
+NS_NewTableCaptionFrame(nsIPresShell* aPresShell,
+ nsIFrame** aNewFrame)
+{
+ NS_PRECONDITION(aNewFrame, "null OUT ptr");
+ if (nsnull == aNewFrame) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsTableCaptionFrame* it = new (aPresShell) nsTableCaptionFrame;
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ *aNewFrame = it;
+ return NS_OK;
+}
+
+// OuterTableReflowState
+
struct OuterTableReflowState {
// The presentation context
@@ -101,28 +137,81 @@ nsresult nsTableOuterFrame::QueryInterface(const nsIID& aIID, void** aInstancePt
}
}
-NS_IMETHODIMP nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
- nsIAtom* aListName,
- nsIFrame* aChildList)
+NS_IMETHODIMP
+nsTableOuterFrame::Init(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow)
{
- mFrames.SetFrames(aChildList);
+ nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent,
+ aContext, aPrevInFlow);
+ if (NS_FAILED(rv) || !mStyleContext) return rv;
- // Set our internal member data
- mInnerTableFrame = aChildList;
- //XXX this should go through the child list looking for a displaytype==caption
- if (1 < mFrames.GetLength()) {
- nsIFrame *child;
- nsresult result = aChildList->GetNextSibling(&child);
- while ((NS_SUCCEEDED(result)) && (nsnull!=child)) {
- const nsStyleDisplay* childDisplay;
- child->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)childDisplay);
- if (NS_STYLE_DISPLAY_TABLE_CAPTION==childDisplay->mDisplay) {
- mCaptionFrame = child;
- break;
- }
- result = child->GetNextSibling(&child);
+#if 0
+ // a 0 width table becomes auto
+ PRBool makeAuto = PR_FALSE;
+ nsStylePosition* position = (nsStylePosition*)mStyleContext->GetMutableStyleData(eStyleStruct_Position);
+ if (position->mWidth.GetUnit() == eStyleUnit_Coord) {
+ if (0 >= position->mWidth.GetCoordValue()) {
+ makeAuto= PR_TRUE;
}
}
+ else if (position->mWidth.GetUnit() == eStyleUnit_Percent) {
+ if (0.0f >= position->mWidth.GetPercentValue()) {
+ makeAuto= PR_TRUE;
+ }
+ }
+
+ if (makeAuto) {
+ position->mWidth = nsStyleCoord(eStyleUnit_Auto);
+ }
+#endif
+ return rv;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::FirstChild(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame** aFirstChild) const
+{
+ NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer");
+ *aFirstChild = (nsLayoutAtoms::captionList == aListName)
+ ? mCaptionFrame : mFrames.FirstChild();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const
+{
+ NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
+ if (aIndex < 0) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ *aListName = nsnull;
+ switch (aIndex) {
+ case NS_TABLE_FRAME_CAPTION_LIST_INDEX:
+ *aListName = nsLayoutAtoms::captionList;
+ NS_ADDREF(*aListName);
+ break;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList)
+{
+ if (nsLayoutAtoms::captionList == aListName) {
+ // the frame constructor already checked for table-caption display type
+ mCaptionFrame = aChildList;
+ }
+ else {
+ mFrames.SetFrames(aChildList);
+ mInnerTableFrame = aChildList;
+ }
return NS_OK;
}
@@ -133,22 +222,18 @@ nsTableOuterFrame::AppendFrames(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
- const nsStyleDisplay* display;
- nsresult rv;
+ nsresult rv;
// We only have two child frames: the inner table and one caption frame.
// The inner frame is provided when we're initialized, and it cannot change
- aFrameList->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
- if (NS_STYLE_DISPLAY_TABLE_CAPTION == display->mDisplay) {
+ if (nsLayoutAtoms::captionList == aListName) {
NS_PRECONDITION(!mCaptionFrame, "already have a caption frame");
// We only support having a single caption frame
if (mCaptionFrame || (LengthOf(aFrameList) > 1)) {
rv = NS_ERROR_UNEXPECTED;
-
} else {
// Insert the caption frame into the child list
mCaptionFrame = aFrameList;
- mInnerTableFrame->SetNextSibling(aFrameList);
// Reflow the new caption frame. It's already marked dirty, so generate a reflow
// command that tells us to reflow our dirty child frames
@@ -186,14 +271,12 @@ nsTableOuterFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
- const nsStyleDisplay* display;
- nsresult rv;
+ nsresult rv;
// We only have two child frames: the inner table and one caption frame.
// The inner frame can't be removed so this should be the caption
- aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
- NS_PRECONDITION(NS_STYLE_DISPLAY_TABLE_CAPTION == display->mDisplay,
- "can't remove inner frame");
+ NS_PRECONDITION(nsLayoutAtoms::captionList == aListName, "can't remove inner frame");
+ NS_PRECONDITION(aOldFrame == mCaptionFrame, "invalid caption frame");
// See if the caption's minimum width impacted the inner table
if (mMinCaptionWidth > mRect.width) {
@@ -205,10 +288,12 @@ nsTableOuterFrame::RemoveFrame(nsIPresContext* aPresContext,
mInnerTableFrame->SetFrameState(frameState);
}
- // Remove the caption frame from the child list and destroy it
- mFrames.DestroyFrame(aPresContext, aOldFrame);
- mCaptionFrame = nsnull;
- mMinCaptionWidth = 0;
+ // Remove the caption frame and destroy it
+ if (mCaptionFrame && (mCaptionFrame == aOldFrame)) {
+ mCaptionFrame->Destroy(aPresContext);
+ mCaptionFrame = nsnull;
+ mMinCaptionWidth = 0;
+ }
// Generate a reflow command so we get reflowed
nsIReflowCommand* reflowCmd;
@@ -235,7 +320,37 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext,
}
#endif
- PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
+ // the remaining code was copied from nsContainerFrame::PaintChildren since
+ // it only paints the primary child list
+
+ const nsStyleDisplay* disp = (const nsStyleDisplay*)
+ mStyleContext->GetStyleData(eStyleStruct_Display);
+
+ // Child elements have the opportunity to override the visibility property
+ // of their parent and display even if the parent is hidden
+ PRBool clipState;
+
+ // If overflow is hidden then set the clip rect so that children
+ // don't leak out of us
+ if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {
+ aRenderingContext.PushState();
+ aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height),
+ nsClipCombine_kIntersect, clipState);
+ }
+
+ if (mCaptionFrame) {
+ PaintChild(aPresContext, aRenderingContext, aDirtyRect, mCaptionFrame, aWhichLayer);
+ }
+ nsIFrame* kid = mFrames.FirstChild();
+ while (nsnull != kid) {
+ PaintChild(aPresContext, aRenderingContext, aDirtyRect, kid, aWhichLayer);
+ kid->GetNextSibling(&kid);
+ }
+
+ if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {
+ aRenderingContext.PopState(clipState);
+ }
+
return NS_OK;
}
@@ -344,8 +459,11 @@ nsresult nsTableOuterFrame::IR_TargetIsChild(nsIPresContext* aPresContext
nsIFrame* aNextFrame)
{
nsresult rv;
- if (!aNextFrame)
+ if (!aNextFrame) {
+ // this will force Reflow to return the height of the last reflow rather than 0
+ aReflowState.y = mRect.height;
return NS_OK;
+ }
if (aNextFrame == mInnerTableFrame) {
rv = IR_TargetIsInnerTableFrame(aPresContext, aDesiredSize, aReflowState, aStatus);
@@ -825,7 +943,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
{
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl en", this, &aReflowState, nsnull);
nsresult rv = NS_OK;
-
// Initialize out parameters
aDesiredSize.width = 0;
aDesiredSize.height = 0;
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h
index 221b3c4e1a5..6a0a54f6caa 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.h
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h
@@ -24,11 +24,21 @@
#include "nscore.h"
#include "nsHTMLContainerFrame.h"
+#include "nsBlockFrame.h"
#include "nsITableLayout.h"
struct OuterTableReflowState;
struct nsStyleTable;
+class nsTableCaptionFrame : public nsBlockFrame
+{
+ public:
+ // nsISupports
+ nsTableCaptionFrame();
+ NS_IMETHOD GetFrameType(nsIAtom** aType) const;
+};
+
+
/* TODO
1. decide if we'll allow subclassing. If so, decide which methods really need to be virtual.
*/
@@ -53,11 +63,24 @@ public:
friend nsresult
NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
+ NS_IMETHOD Init(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow);
+
/** @see nsIFrame::SetInitialChildList */
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
+ NS_IMETHOD FirstChild(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame** aFirstChild) const;
+
+ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const;
+
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
@@ -237,7 +260,7 @@ protected:
private:
/** used to keep track of this frame's children */
- nsIFrame *mInnerTableFrame;
+ nsIFrame *mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame *mCaptionFrame;
/** used to track caption max element size */
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index c3c210af812..7a70fd82e52 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -803,10 +803,14 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Newly inserted frame
reason = eReflowReason_Initial;
- // Use an unconstrained width so we can get the child's maximum
- // width
+ // Use an unconstrained width so we can get the child's maximum width
// XXX What about fixed layout tables?
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ // request to get the max element size if not already so
+ if (!kidMaxElementSize) {
+ kidMaxElementSize = &localKidMaxElementSize;
+ desiredSize.maxElementSize = kidMaxElementSize;
+ }
}
}
diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp
index ab088eeafe6..eeeac9c2ba3 100644
--- a/mozilla/layout/tables/nsTableCellFrame.cpp
+++ b/mozilla/layout/tables/nsTableCellFrame.cpp
@@ -691,22 +691,20 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
DebugCheckChildSize(firstKid, kidSize, availSize, (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth));
#endif
- PRBool useInsets = PR_TRUE;
// 0 dimensioned cells need to be treated specially in Standard/NavQuirks mode
// see testcase "emptyCells.html"
- if (NS_UNCONSTRAINEDSIZE == kidReflowState.availableWidth) {
- if ((0 == kidSize.width) || (0 == kidSize.height)) {
- //if ((0 == kidSize.width) && (0 == kidSize.height)) { // XXX why was this &&
- SetContentEmpty(PR_TRUE);
- useInsets = PR_FALSE;
+ if ((0 == kidSize.width) || (0 == kidSize.height)) { // XXX why was this &&
+ SetContentEmpty(PR_TRUE);
+ if (NS_UNCONSTRAINEDSIZE == kidReflowState.availableWidth) {
// need to reduce the insets by border if the cell is empty
leftInset -= border.left;
rightInset -= border.right;
topInset -= border.top;
bottomInset -= border.bottom;
}
- else
- SetContentEmpty(PR_FALSE);
+ }
+ else {
+ SetContentEmpty(PR_FALSE);
}
const nsStylePosition* pos;
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index a280179bd91..83575485286 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -58,6 +58,7 @@
#include "nsIDOMHTMLBodyElement.h"
#include "nsISizeOfHandler.h"
#include "nsIScrollableFrame.h"
+#include "nsHTMLReflowCommand.h"
NS_DEF_PTR(nsIStyleContext);
NS_DEF_PTR(nsIContent);
@@ -84,6 +85,8 @@ PRBool nsDebugTable::gRflRow = PR_TRUE;
PRBool nsDebugTable::gRflCell = PR_TRUE;
PRBool nsDebugTable::gRflArea = PR_TRUE;
#endif
+static PRInt32 gRflCount = 0;
+
/* ----------- InnerTableReflowState ---------- */
struct InnerTableReflowState {
@@ -4678,7 +4681,11 @@ void nsTableFrame::DebugReflow(char* aMessage,
printf("rea=%d av=(%s,%s) ", aState->reason, width, height);
PrettyUC(aState->mComputedWidth, width);
PrettyUC(aState->mComputedHeight, height);
- printf("comp=(%s,%s) \n", width, height);
+ printf("comp=(%s,%s) count=%d \n", width, height, gRflCount);
+ gRflCount++;
+ //if (32 == gRflCount) {
+ // NS_ASSERTION(PR_FALSE, "stop");
+ //}
}
if (aMetrics) {
if (aState) {
diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp
index d8082427efb..abfe42508a5 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.cpp
+++ b/mozilla/layout/tables/nsTableOuterFrame.cpp
@@ -36,6 +36,42 @@
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
+#define NS_TABLE_FRAME_CAPTION_LIST_INDEX 0
+
+// caption frame
+nsTableCaptionFrame::nsTableCaptionFrame()
+{
+ // shrink wrap
+ SetFlags(NS_BLOCK_SPACE_MGR|NS_BLOCK_WRAP_SIZE);
+}
+
+NS_IMETHODIMP
+nsTableCaptionFrame::GetFrameType(nsIAtom** aType) const
+{
+ NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
+ *aType = nsLayoutAtoms::tableCaptionFrame;
+ NS_ADDREF(*aType);
+ return NS_OK;
+}
+
+nsresult
+NS_NewTableCaptionFrame(nsIPresShell* aPresShell,
+ nsIFrame** aNewFrame)
+{
+ NS_PRECONDITION(aNewFrame, "null OUT ptr");
+ if (nsnull == aNewFrame) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsTableCaptionFrame* it = new (aPresShell) nsTableCaptionFrame;
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ *aNewFrame = it;
+ return NS_OK;
+}
+
+// OuterTableReflowState
+
struct OuterTableReflowState {
// The presentation context
@@ -101,28 +137,81 @@ nsresult nsTableOuterFrame::QueryInterface(const nsIID& aIID, void** aInstancePt
}
}
-NS_IMETHODIMP nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
- nsIAtom* aListName,
- nsIFrame* aChildList)
+NS_IMETHODIMP
+nsTableOuterFrame::Init(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow)
{
- mFrames.SetFrames(aChildList);
+ nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent,
+ aContext, aPrevInFlow);
+ if (NS_FAILED(rv) || !mStyleContext) return rv;
- // Set our internal member data
- mInnerTableFrame = aChildList;
- //XXX this should go through the child list looking for a displaytype==caption
- if (1 < mFrames.GetLength()) {
- nsIFrame *child;
- nsresult result = aChildList->GetNextSibling(&child);
- while ((NS_SUCCEEDED(result)) && (nsnull!=child)) {
- const nsStyleDisplay* childDisplay;
- child->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)childDisplay);
- if (NS_STYLE_DISPLAY_TABLE_CAPTION==childDisplay->mDisplay) {
- mCaptionFrame = child;
- break;
- }
- result = child->GetNextSibling(&child);
+#if 0
+ // a 0 width table becomes auto
+ PRBool makeAuto = PR_FALSE;
+ nsStylePosition* position = (nsStylePosition*)mStyleContext->GetMutableStyleData(eStyleStruct_Position);
+ if (position->mWidth.GetUnit() == eStyleUnit_Coord) {
+ if (0 >= position->mWidth.GetCoordValue()) {
+ makeAuto= PR_TRUE;
}
}
+ else if (position->mWidth.GetUnit() == eStyleUnit_Percent) {
+ if (0.0f >= position->mWidth.GetPercentValue()) {
+ makeAuto= PR_TRUE;
+ }
+ }
+
+ if (makeAuto) {
+ position->mWidth = nsStyleCoord(eStyleUnit_Auto);
+ }
+#endif
+ return rv;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::FirstChild(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame** aFirstChild) const
+{
+ NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer");
+ *aFirstChild = (nsLayoutAtoms::captionList == aListName)
+ ? mCaptionFrame : mFrames.FirstChild();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const
+{
+ NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
+ if (aIndex < 0) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ *aListName = nsnull;
+ switch (aIndex) {
+ case NS_TABLE_FRAME_CAPTION_LIST_INDEX:
+ *aListName = nsLayoutAtoms::captionList;
+ NS_ADDREF(*aListName);
+ break;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList)
+{
+ if (nsLayoutAtoms::captionList == aListName) {
+ // the frame constructor already checked for table-caption display type
+ mCaptionFrame = aChildList;
+ }
+ else {
+ mFrames.SetFrames(aChildList);
+ mInnerTableFrame = aChildList;
+ }
return NS_OK;
}
@@ -133,22 +222,18 @@ nsTableOuterFrame::AppendFrames(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
- const nsStyleDisplay* display;
- nsresult rv;
+ nsresult rv;
// We only have two child frames: the inner table and one caption frame.
// The inner frame is provided when we're initialized, and it cannot change
- aFrameList->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
- if (NS_STYLE_DISPLAY_TABLE_CAPTION == display->mDisplay) {
+ if (nsLayoutAtoms::captionList == aListName) {
NS_PRECONDITION(!mCaptionFrame, "already have a caption frame");
// We only support having a single caption frame
if (mCaptionFrame || (LengthOf(aFrameList) > 1)) {
rv = NS_ERROR_UNEXPECTED;
-
} else {
// Insert the caption frame into the child list
mCaptionFrame = aFrameList;
- mInnerTableFrame->SetNextSibling(aFrameList);
// Reflow the new caption frame. It's already marked dirty, so generate a reflow
// command that tells us to reflow our dirty child frames
@@ -186,14 +271,12 @@ nsTableOuterFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
- const nsStyleDisplay* display;
- nsresult rv;
+ nsresult rv;
// We only have two child frames: the inner table and one caption frame.
// The inner frame can't be removed so this should be the caption
- aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
- NS_PRECONDITION(NS_STYLE_DISPLAY_TABLE_CAPTION == display->mDisplay,
- "can't remove inner frame");
+ NS_PRECONDITION(nsLayoutAtoms::captionList == aListName, "can't remove inner frame");
+ NS_PRECONDITION(aOldFrame == mCaptionFrame, "invalid caption frame");
// See if the caption's minimum width impacted the inner table
if (mMinCaptionWidth > mRect.width) {
@@ -205,10 +288,12 @@ nsTableOuterFrame::RemoveFrame(nsIPresContext* aPresContext,
mInnerTableFrame->SetFrameState(frameState);
}
- // Remove the caption frame from the child list and destroy it
- mFrames.DestroyFrame(aPresContext, aOldFrame);
- mCaptionFrame = nsnull;
- mMinCaptionWidth = 0;
+ // Remove the caption frame and destroy it
+ if (mCaptionFrame && (mCaptionFrame == aOldFrame)) {
+ mCaptionFrame->Destroy(aPresContext);
+ mCaptionFrame = nsnull;
+ mMinCaptionWidth = 0;
+ }
// Generate a reflow command so we get reflowed
nsIReflowCommand* reflowCmd;
@@ -235,7 +320,37 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext,
}
#endif
- PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
+ // the remaining code was copied from nsContainerFrame::PaintChildren since
+ // it only paints the primary child list
+
+ const nsStyleDisplay* disp = (const nsStyleDisplay*)
+ mStyleContext->GetStyleData(eStyleStruct_Display);
+
+ // Child elements have the opportunity to override the visibility property
+ // of their parent and display even if the parent is hidden
+ PRBool clipState;
+
+ // If overflow is hidden then set the clip rect so that children
+ // don't leak out of us
+ if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {
+ aRenderingContext.PushState();
+ aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height),
+ nsClipCombine_kIntersect, clipState);
+ }
+
+ if (mCaptionFrame) {
+ PaintChild(aPresContext, aRenderingContext, aDirtyRect, mCaptionFrame, aWhichLayer);
+ }
+ nsIFrame* kid = mFrames.FirstChild();
+ while (nsnull != kid) {
+ PaintChild(aPresContext, aRenderingContext, aDirtyRect, kid, aWhichLayer);
+ kid->GetNextSibling(&kid);
+ }
+
+ if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {
+ aRenderingContext.PopState(clipState);
+ }
+
return NS_OK;
}
@@ -344,8 +459,11 @@ nsresult nsTableOuterFrame::IR_TargetIsChild(nsIPresContext* aPresContext
nsIFrame* aNextFrame)
{
nsresult rv;
- if (!aNextFrame)
+ if (!aNextFrame) {
+ // this will force Reflow to return the height of the last reflow rather than 0
+ aReflowState.y = mRect.height;
return NS_OK;
+ }
if (aNextFrame == mInnerTableFrame) {
rv = IR_TargetIsInnerTableFrame(aPresContext, aDesiredSize, aReflowState, aStatus);
@@ -825,7 +943,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
{
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl en", this, &aReflowState, nsnull);
nsresult rv = NS_OK;
-
// Initialize out parameters
aDesiredSize.width = 0;
aDesiredSize.height = 0;
diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h
index 221b3c4e1a5..6a0a54f6caa 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.h
+++ b/mozilla/layout/tables/nsTableOuterFrame.h
@@ -24,11 +24,21 @@
#include "nscore.h"
#include "nsHTMLContainerFrame.h"
+#include "nsBlockFrame.h"
#include "nsITableLayout.h"
struct OuterTableReflowState;
struct nsStyleTable;
+class nsTableCaptionFrame : public nsBlockFrame
+{
+ public:
+ // nsISupports
+ nsTableCaptionFrame();
+ NS_IMETHOD GetFrameType(nsIAtom** aType) const;
+};
+
+
/* TODO
1. decide if we'll allow subclassing. If so, decide which methods really need to be virtual.
*/
@@ -53,11 +63,24 @@ public:
friend nsresult
NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
+ NS_IMETHOD Init(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow);
+
/** @see nsIFrame::SetInitialChildList */
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
+ NS_IMETHOD FirstChild(nsIPresContext* aPresContext,
+ nsIAtom* aListName,
+ nsIFrame** aFirstChild) const;
+
+ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const;
+
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
@@ -237,7 +260,7 @@ protected:
private:
/** used to keep track of this frame's children */
- nsIFrame *mInnerTableFrame;
+ nsIFrame *mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame *mCaptionFrame;
/** used to track caption max element size */
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index c3c210af812..7a70fd82e52 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -803,10 +803,14 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Newly inserted frame
reason = eReflowReason_Initial;
- // Use an unconstrained width so we can get the child's maximum
- // width
+ // Use an unconstrained width so we can get the child's maximum width
// XXX What about fixed layout tables?
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ // request to get the max element size if not already so
+ if (!kidMaxElementSize) {
+ kidMaxElementSize = &localKidMaxElementSize;
+ desiredSize.maxElementSize = kidMaxElementSize;
+ }
}
}