Bug 379349. Add support for 'overflow containers' --- special frame continuations that do not map any content of their own, but serve only as containers for laying out children that overflowed their parents' content height. patch by fantasai, r+sr=eli,roc

This commit is contained in:
2007-07-25 21:03:29 -07:00
parent c423f0d127
commit e3742c090c
22 changed files with 1157 additions and 211 deletions

View File

@@ -75,7 +75,14 @@ public:
virtual nsIFrame* GetContentInsertionFrame() {
return GetFirstChild(nsnull)->GetContentInsertionFrame();
}
virtual nsresult StealFrame(nsPresContext* aPresContext,
nsIFrame* aChild,
PRBool aForceNormal)
{ // nsColumnSetFrame keeps overflow containers in main child list
return nsContainerFrame::StealFrame(aPresContext, aChild, PR_TRUE);
}
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
@@ -440,9 +447,9 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
// might be pullable back to this column. We can't skip if it's the last child
// because we need to obtain the bottom margin.
PRBool skipIncremental = !(GetStateBits() & NS_FRAME_IS_DIRTY)
&& !(child->GetStateBits() & NS_FRAME_IS_DIRTY)
&& !NS_SUBTREE_DIRTY(child)
&& child->GetNextSibling()
&& !(child->GetNextSibling()->GetStateBits() & NS_FRAME_IS_DIRTY);
&& !NS_SUBTREE_DIRTY(child->GetNextSibling());
// If we need to pull up content from the prev-in-flow then this is not just
// a height shrink. The prev in flow will have set the dirty bit.
// Check the overflow rect YMost instead of just the child's content height. The child
@@ -457,8 +464,11 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
MoveChildTo(this, child, childOrigin);
// If this is the last frame then make sure we get the right status
if (child->GetNextSibling()) {
aStatus = NS_FRAME_NOT_COMPLETE;
nsIFrame* kidNext = child->GetNextSibling();
if (kidNext) {
aStatus = (kidNext->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)
? NS_FRAME_OVERFLOW_INCOMPLETE
: NS_FRAME_NOT_COMPLETE;
} else {
aStatus = mLastFrameStatus;
}
@@ -536,7 +546,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
// Build a continuation column if necessary
nsIFrame* kidNextInFlow = child->GetNextInFlow();
if (NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus)) {
if (NS_FRAME_IS_FULLY_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus)) {
NS_ASSERTION(!kidNextInFlow, "next in flow should have been deleted");
break;
} else {
@@ -557,6 +567,21 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
break;
}
}
// Make sure we reflow a next-in-flow when it switches between being
// normal or overflow container
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
if (!(kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
reflowNext = PR_TRUE;
kidNextInFlow->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
}
else if (kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
reflowNext = PR_TRUE;
kidNextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if (columnCount >= aConfig.mBalanceColCount) {
// No more columns allowed here. Stop.