diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp
index 570b4925df19..ae8d6864bd41 100644
--- a/layout/html/table/src/nsTableRowGroupFrame.cpp
+++ b/layout/html/table/src/nsTableRowGroupFrame.cpp
@@ -410,17 +410,6 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
for ( ; nsnull != kidFrame; )
{
- if (ExcludeFrameFromReflow(kidFrame)) {
- // The tree widget has some frames that aren't reflowed by
- // the normal row group reflow.
- if (PR_FALSE==aDoSiblings)
- break;
-
- // Get the next child
- GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame);
- continue;
- }
-
nsSize kidAvailSize(aReflowState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
@@ -758,7 +747,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
rowGroupHeight += rowHeights[rowIndex];
rowIndex++;
}
- else if (!ExcludeFrameFromReflow(rowFrame)) {
+ else {
// Anything that isn't a row contributes to the row group's total height.
nsSize frameSize;
rowFrame->GetSize(frameSize);
diff --git a/layout/html/table/src/nsTableRowGroupFrame.h b/layout/html/table/src/nsTableRowGroupFrame.h
index c95ae5909b4f..0f53c7cd86da 100644
--- a/layout/html/table/src/nsTableRowGroupFrame.h
+++ b/layout/html/table/src/nsTableRowGroupFrame.h
@@ -295,7 +295,6 @@ protected:
nsReflowStatus& aStatus,
nsReflowReason aReason) { return NS_OK; };
- virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame) { return PR_FALSE; };
virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); };
virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); };
void GetNextRowSibling(nsIFrame** aRowFrame);
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index 570b4925df19..ae8d6864bd41 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -410,17 +410,6 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
for ( ; nsnull != kidFrame; )
{
- if (ExcludeFrameFromReflow(kidFrame)) {
- // The tree widget has some frames that aren't reflowed by
- // the normal row group reflow.
- if (PR_FALSE==aDoSiblings)
- break;
-
- // Get the next child
- GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame);
- continue;
- }
-
nsSize kidAvailSize(aReflowState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
@@ -758,7 +747,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
rowGroupHeight += rowHeights[rowIndex];
rowIndex++;
}
- else if (!ExcludeFrameFromReflow(rowFrame)) {
+ else {
// Anything that isn't a row contributes to the row group's total height.
nsSize frameSize;
rowFrame->GetSize(frameSize);
diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h
index c95ae5909b4f..0f53c7cd86da 100644
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -295,7 +295,6 @@ protected:
nsReflowStatus& aStatus,
nsReflowReason aReason) { return NS_OK; };
- virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame) { return PR_FALSE; };
virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); };
virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); };
void GetNextRowSibling(nsIFrame** aRowFrame);
diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.cpp b/layout/xul/base/src/nsTreeRowGroupFrame.cpp
index 110dc66ab1eb..0ea6ab053a60 100644
--- a/layout/xul/base/src/nsTreeRowGroupFrame.cpp
+++ b/layout/xul/base/src/nsTreeRowGroupFrame.cpp
@@ -73,6 +73,14 @@ nsTreeRowGroupFrame::~nsTreeRowGroupFrame()
NS_IF_RELEASE(mContentChain);
}
+NS_IMETHODIMP
+nsTreeRowGroupFrame::DeleteFrame(nsIPresContext& aPresContext)
+{
+ if (mScrollbar)
+ mScrollbar->DeleteFrame(aPresContext);
+ return NS_OK;
+}
+
NS_IMPL_ADDREF(nsTreeRowGroupFrame)
NS_IMPL_RELEASE(nsTreeRowGroupFrame)
@@ -201,6 +209,68 @@ nsTreeRowGroupFrame::GetFirstRowContent(nsIContent** aResult)
}
}
+void
+nsTreeRowGroupFrame::FindRowContentAtIndex(PRInt32& aIndex, nsIContent* aParent,
+ nsIContent** aResult)
+{
+ // Init to nsnull.
+ *aResult = nsnull;
+
+ // It disappoints me that this function is completely tied to the content nodes,
+ // but I can't see any other way to handle this. I don't have the frames, so I have nothing
+ // else to fall back on but the content nodes.
+
+ PRInt32 childCount;
+ aParent->ChildCount(childCount);
+
+ for (PRInt32 i = 0; i < childCount; i++) {
+ nsCOMPtr childContent;
+ aParent->ChildAt(i, *getter_AddRefs(childContent));
+ nsCOMPtr tag;
+ childContent->GetTag(*getter_AddRefs(tag));
+ if (tag.get() == nsXULAtoms::treerow) {
+ aIndex--;
+ if (aIndex < 0) {
+ *aResult = childContent;
+ NS_IF_ADDREF(*aResult);
+ return;
+ }
+ }
+ else if (tag.get() == nsXULAtoms::treeitem) {
+ // Descend into this row group and try to find the next row.
+ FindRowContentAtIndex(aIndex, childContent, aResult);
+ if (aIndex < 0)
+ return;
+
+ // If it's open, descend into its treechildren.
+ nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open"));
+ nsString isOpen;
+ childContent->GetAttribute(kNameSpaceID_None, openAtom, isOpen);
+ if (isOpen == "true") {
+ // Find the node.
+ PRInt32 childContentCount;
+ nsCOMPtr grandChild;
+ childContent->ChildCount(childContentCount);
+
+ PRInt32 j;
+ for (j = childContentCount-1; j >= 0; j--) {
+
+ childContent->ChildAt(j, *getter_AddRefs(grandChild));
+ nsCOMPtr grandChildTag;
+ grandChild->GetTag(*getter_AddRefs(grandChildTag));
+ if (grandChildTag.get() == nsXULAtoms::treechildren)
+ break;
+ }
+ if (j >= 0 && grandChild)
+ FindRowContentAtIndex(aIndex, grandChild, aResult);
+
+ if (aIndex < 0)
+ return;
+ }
+ }
+ }
+}
+
void
nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpwardHint,
nsIContent* aDownwardHint, nsIContent** aResult)
@@ -215,6 +285,10 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward
nsCOMPtr parentContent;
if (aUpwardHint) {
aUpwardHint->GetParent(*getter_AddRefs(parentContent));
+ if (!parentContent) {
+ NS_ERROR("Parent content should not be NULL!");
+ return;
+ }
parentContent->IndexOf(aUpwardHint, index);
}
else if (aDownwardHint) {
@@ -326,14 +400,22 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldI
else {
// Just blow away all our frames, but keep a content chain
// as a hint to figure out how to build the frames.
- NS_ERROR("Not yet implemented!\n");
- //mFrames.DeleteFrames(aPresContext); // Destroys everything.
+ // Remove the scrollbar first.
+ mFrames.DeleteFrames(aPresContext);
+ nsCOMPtr topRowContent;
+ FindRowContentAtIndex(aNewIndex, mContent, getter_AddRefs(topRowContent));
+ ConstructContentChain(topRowContent);
}
// Invalidate the cell map and column cache.
tableFrame->InvalidateCellMap();
tableFrame->InvalidateColumnCache();
+ mTopFrame = mBottomFrame = nsnull; // Make sure everything is cleared out.
+
+ // Force a reflow.
+ OnContentAdded(aPresContext);
+
return NS_OK;
}
@@ -349,6 +431,7 @@ nsTreeRowGroupFrame::SetScrollbarFrame(nsIFrame* aFrame)
{
mIsLazy = PR_TRUE;
mScrollbar = aFrame;
+
nsCOMPtr sliderAtom = dont_AddRef(NS_NewAtom("slider"));
nsCOMPtr incrementAtom = dont_AddRef(NS_NewAtom("increment"));
nsCOMPtr pageIncrementAtom = dont_AddRef(NS_NewAtom("pageincrement"));
@@ -400,6 +483,32 @@ nsTreeRowGroupFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
return nsTableRowGroupFrame::GetFrameForPoint(aPoint, aFrame);
}
+NS_IMETHODIMP
+nsTreeRowGroupFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const
+{
+ nsCOMPtr scrollList = dont_AddRef(NS_NewAtom("scrollbarlist"));
+ if (scrollList.get() == aListName) {
+ *aFirstChild = mScrollbarList.FirstChild();
+ return NS_OK;
+ }
+
+ nsTableRowGroupFrame::FirstChild(aListName, aFirstChild);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTreeRowGroupFrame::GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const
+{
+ *aListName = nsnull;
+
+ if (aIndex == 0) {
+ *aListName = NS_NewAtom("scrollbarlist"); // AddRefs
+ }
+
+ return NS_OK;
+}
+
void nsTreeRowGroupFrame::PaintChildren(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@@ -479,29 +588,21 @@ nsTreeRowGroupFrame::ReflowBeforeRowLayout(nsIPresContext& aPresContext,
return rv;
}
-
-PRBool nsTreeRowGroupFrame::ExcludeFrameFromReflow(nsIFrame* aFrame)
-{
- if (aFrame == mScrollbar)
- return PR_TRUE;
- else return PR_FALSE;
-}
-
void nsTreeRowGroupFrame::LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult)
{
if (aStartFrame == nsnull)
{
- aStartFrame = mFrames.FirstChild();
+ *aResult = mFrames.FirstChild();
}
- else aStartFrame->GetNextSibling(&aStartFrame);
+ else aStartFrame->GetNextSibling(aResult);
- if (!aStartFrame) {
- *aResult = nsnull;
- } else if (aStartFrame != mScrollbar) {
- *aResult = aStartFrame;
- } else {
- aStartFrame->GetNextSibling(&aStartFrame);
- *aResult = aStartFrame;
+ if (mScrollbar && (*aResult == mScrollbar)) {
+ // Get this out of our flow.
+ mScrollbar->GetNextSibling(aResult);
+ mFrames.RemoveFrame(mScrollbar);
+
+ // Put it into a special list of our own.
+ mScrollbarList.AppendFrame(this, mScrollbar);
}
}
diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.h b/layout/xul/base/src/nsTreeRowGroupFrame.h
index ef267afd87aa..fcd158bd77c1 100644
--- a/layout/xul/base/src/nsTreeRowGroupFrame.h
+++ b/layout/xul/base/src/nsTreeRowGroupFrame.h
@@ -30,7 +30,9 @@ class nsTreeRowGroupFrame : public nsTableRowGroupFrame, public nsIScrollbarList
public:
friend nsresult NS_NewTreeRowGroupFrame(nsIFrame** aNewFrame);
- virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame);
+ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const;
+ NS_IMETHOD FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const;
void SetScrollbarFrame(nsIFrame* aFrame);
void SetFrameConstructor(nsCSSFrameConstructor* aFrameConstructor) { mFrameConstructor = aFrameConstructor; };
@@ -93,8 +95,12 @@ protected:
void ConstructContentChain(nsIContent* aRowContent);
void FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpwardHint,
nsIContent* aDownwardHint, nsIContent** aResult);
+ void FindRowContentAtIndex(PRInt32& aIndex, nsIContent* aParent,
+ nsIContent** aResult);
void GetFirstRowContent(nsIContent** aRowContent);
+ NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
+
protected: // Data Members
nsIFrame* mTopFrame; // The current topmost frame in the view.
nsIFrame* mBottomFrame; // The current bottom frame in the view.
@@ -104,7 +110,8 @@ protected: // Data Members
PRBool mIsFull; // Whether or not we have any more room.
nsIFrame* mScrollbar; // Our scrollbar.
-
+ nsFrameList mScrollbarList; // A frame list that holds our scrollbar.
+
nsISupportsArray* mContentChain; // Our content chain
nsCSSFrameConstructor* mFrameConstructor; // We don't own this. (No addref/release allowed, punk.)