зеркало из https://github.com/mozilla/pjs.git
simple tables now paginate nicely. Some more complex tables
also paginate ok, though resizing in paginated mode doesn't work yet. Captions still don't work.
This commit is contained in:
Родитель
a57f6b591d
Коммит
e9fef51c60
|
@ -466,7 +466,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflow( nsIPresContext* aPresContext,
|
|||
PRIntervalTime startTime = PR_IntervalNow();
|
||||
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf ("*** tableframe reflow\t\t%d\n", this);
|
||||
printf ("*** tableframe reflow\t\t%p\n", this);
|
||||
|
||||
if (PR_TRUE==NeedsReflow(aMaxSize))
|
||||
{
|
||||
|
@ -730,15 +730,14 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
|
|||
// Did we successfully reflow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = ReflowUnmappedChildren(aPresContext, state, aMaxElementSize);
|
||||
|
@ -822,7 +821,6 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
InnerTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
|
@ -889,7 +887,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
// having to push children, we have the correct value to hand to
|
||||
// PushChildren.
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
@ -921,32 +919,22 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it's not our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
|
||||
// Since we are giving the next-in-flow our last child, we
|
||||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// give it our original mLastContentIsComplete too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
PushChildren(kidFrame, prevKidFrame, originalLastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -956,8 +944,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
|
@ -965,21 +952,24 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
// Special handling for incomplete children
|
||||
if (frNotComplete == status) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Insert the frame. We'll reflow it next pass through the loop
|
||||
// Add the continuing frame to the sibling list
|
||||
nsIFrame* nextSib = kidFrame->GetNextSibling();
|
||||
continuingFrame->SetNextSibling(nextSib);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
@ -990,11 +980,19 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
|
@ -1003,10 +1001,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
// Update the child count
|
||||
mChildCount = childCount;
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
|
||||
// Set the last content offset based on the last child we mapped.
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
NS_POSTCONDITION(LastChild()->GetIndexInParent() == mLastContentOffset, "bad last content offset");
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -1042,8 +1037,8 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -1066,14 +1061,13 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableFrame* nextInFlow = (nsTableFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableFrame* nextInFlow = (nsTableFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -1081,125 +1075,127 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetHeight() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -1228,28 +1224,7 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pullup %sok (childCount=%d) [%d,%d,%c]\n",
|
||||
(result ? "" : "NOT "),
|
||||
mChildCount,
|
||||
mFirstContentOffset, mLastContentOffset,
|
||||
(mLastContentIsComplete ? 'T' : 'F'));
|
||||
#ifdef NOISY_FLOW
|
||||
{
|
||||
nsTableFrame* flow = (nsTableFrame*) mNextInFlow;
|
||||
while (flow != 0) {
|
||||
printf(" %p: [%d,%d,%c]\n",
|
||||
flow, flow->mFirstContentOffset, flow->mLastContentOffset,
|
||||
(flow->mLastContentIsComplete ? 'T' : 'F'));
|
||||
flow = (nsTableFrame*) flow->mNextInFlow;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -1270,8 +1245,8 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
nsIFrame* kidPrevInFlow = nsnull;
|
||||
ReflowStatus result = frNotComplete;
|
||||
nsIFrame* kidPrevInFlow = nsnull;
|
||||
ReflowStatus result = frNotComplete;
|
||||
|
||||
// If we have no children and we have a prev-in-flow then we need to pick
|
||||
// up where it left off. If we have children, e.g. we're being resized, then
|
||||
|
@ -1286,14 +1261,13 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidPrevInFlow = prev->LastChild();
|
||||
}
|
||||
}
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Place our children, one at a time, until we are out of children
|
||||
// Place our children, one at a time until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
nsIFrame* prevKidFrame = LastChild(); // XXX remember this...
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
for (;;) {
|
||||
// Get the next content object
|
||||
|
@ -1310,16 +1284,14 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
|
||||
// Resolve style
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* kidStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(kid, this);
|
||||
|
||||
// Figure out how we should treat the child
|
||||
nsIFrame* kidFrame;
|
||||
nsStyleMolecule* kidMol =
|
||||
(nsStyleMolecule*)kidStyleContext->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
nsIFrame* kidFrame;
|
||||
ReflowStatus status;
|
||||
|
||||
// Create a child frame
|
||||
if (nsnull == kidPrevInFlow) {
|
||||
|
@ -1331,131 +1303,72 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
} else {
|
||||
kidFrame = kidPrevInFlow->CreateContinuingFrame(aPresContext, this);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Link the child frame into the list of children and update the
|
||||
// child count
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status = ReflowChild(kidFrame,aPresContext, kidSize,
|
||||
aState.availSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child. Add the frame to our overflow list
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
mOverflowList = kidFrame;
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Link child frame into the list of children
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(nsnull == prevKidFrame->GetNextSibling(), "bad append");
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
} else {
|
||||
NS_ASSERTION(nsnull == mFirstChild, "bad create");
|
||||
mFirstChild = kidFrame;
|
||||
mFirstChild = kidFrame; // our first child
|
||||
SetFirstContentOffset(kidFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
|
||||
do {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics desiredSize;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing
|
||||
if (kidAvailSize.height > 0) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((nsnull != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height))) {
|
||||
// The child's height is too big to fit in our remaining
|
||||
// space, and it's not our first child.
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
NS_ASSERTION(nsnull == mNextInFlow, "whoops");
|
||||
|
||||
// Chop off the part of our child list that's being overflowed
|
||||
NS_ASSERTION(prevKidFrame->GetNextSibling() == kidFrame, "bad list");
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
|
||||
// Create overflow list
|
||||
mOverflowList = kidFrame;
|
||||
|
||||
// Fixup child count by subtracting off the number of children
|
||||
// that just ended up on the reflow list.
|
||||
PRInt32 overflowKids = 0;
|
||||
nsIFrame* f = kidFrame;
|
||||
while (nsnull != f) {
|
||||
overflowKids++;
|
||||
f = f->GetNextSibling();
|
||||
}
|
||||
mChildCount -= overflowKids;
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
topMargin = 0;
|
||||
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// Child didn't complete so create a continuing frame
|
||||
kidPrevInFlow = kidFrame;
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
|
||||
// XXX We probably shouldn't assume that there is no room for
|
||||
// the continuation
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
|
||||
prevKidFrame = kidFrame;
|
||||
kidPrevInFlow = nsnull;
|
||||
|
||||
// Update the kidIndex
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
|
||||
// Did the child complete?
|
||||
if (frNotComplete == status) {
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space
|
||||
mLastContentIsComplete = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
kidPrevInFlow = nsnull;
|
||||
}
|
||||
|
||||
done:
|
||||
// Update the content mapping
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
if (0 != mChildCount) {
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
#endif
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Now I've got all the cells laid out in an infinite space.
|
||||
For each column, use the min size for each cell in that column
|
||||
|
@ -2254,6 +2167,7 @@ nsVoidArray * nsTableFrame::GetColumnLayoutData()
|
|||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
NS_ASSERTION(nsnull!=firstInFlow->mColumnLayoutData, "illegal state -- no column layout data");
|
||||
return firstInFlow->mColumnLayoutData;
|
||||
}
|
||||
|
||||
|
@ -2463,9 +2377,18 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
|
|||
else
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state");
|
||||
#ifdef DEBUG
|
||||
nsVoidArray *cld = GetColumnLayoutData();
|
||||
NS_ASSERTION(nsnull!=cld, "no column layout data");
|
||||
PRInt32 numCols = cld->Count();
|
||||
NS_ASSERTION (numCols > aColIndex, "bad arg, col index out of bounds");
|
||||
#endif
|
||||
if (nsnull!=mColumnWidths)
|
||||
result = mColumnWidths[aColIndex];
|
||||
}
|
||||
|
||||
//printf("GET_COL_WIDTH: %p, FIF=%p getting col %d and returning %d\n", this, firstInFlow, aColIndex, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2473,6 +2396,7 @@ void nsTableFrame::SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth)
|
|||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
//printf("SET_COL_WIDTH: %p, FIF=%p setting col %d to %d\n", this, firstInFlow, aColIndex, aWidth);
|
||||
if (this!=firstInFlow)
|
||||
firstInFlow->SetColumnWidth(aColIndex, aWidth);
|
||||
else
|
||||
|
|
|
@ -223,7 +223,6 @@ protected:
|
|||
InnerTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
|||
|
||||
struct OuterTableReflowState {
|
||||
|
||||
// The presentation context
|
||||
nsIPresContext *pc;
|
||||
|
||||
// The body's style molecule
|
||||
nsStyleMolecule* mol;
|
||||
|
||||
|
@ -74,6 +77,7 @@ struct OuterTableReflowState {
|
|||
const nsSize& aMaxSize,
|
||||
nsStyleMolecule* aMol)
|
||||
{
|
||||
pc = aPresContext;
|
||||
mol = aMol;
|
||||
availSize.width = aMaxSize.width;
|
||||
availSize.height = aMaxSize.height;
|
||||
|
@ -254,19 +258,18 @@ nsIFrame::ReflowStatus nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresCont
|
|||
// Did we successfully relow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// nothing to do, we will never have unmapped children!
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
NS_ABORT(); // huge error for tables!
|
||||
} else {
|
||||
// We were unable to pull-up all the existing frames from the
|
||||
// next in flow
|
||||
// We were unable to pull-up all the existing frames from the next in flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +306,18 @@ nsIFrame::ReflowStatus nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresCont
|
|||
// replace with a check that does not assume linear placement of children
|
||||
// PostReflowCheck(status);
|
||||
#endif
|
||||
// REMOVE ME!
|
||||
/*
|
||||
nsIFrame *next = this;
|
||||
nsIFrame *root=nsnull;
|
||||
while (nsnull!=next)
|
||||
{
|
||||
root = next;
|
||||
next = next->GetGeometricParent();
|
||||
}
|
||||
root->List();
|
||||
*/
|
||||
// end REMOVE ME!
|
||||
|
||||
return status;
|
||||
|
||||
|
@ -332,11 +347,9 @@ nscoord nsTableOuterFrame::GetTopMarginFor(nsIPresContext* aCX,
|
|||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableOuterFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
void nsTableOuterFrame::PlaceChild( OuterTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
|
@ -411,7 +424,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
// having to push children, we have the correct value to hand to
|
||||
// PushChildren.
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
@ -419,7 +432,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
nsSize kidAvailSize(aState.innerTableMaxSize.width, aState.availSize.height);
|
||||
nsReflowMetrics desiredSize;
|
||||
nsReflowMetrics kidSize;
|
||||
nsIFrame::ReflowStatus status;
|
||||
|
||||
SetReflowState(aState, kidFrame);
|
||||
|
@ -448,42 +461,32 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize,
|
||||
kidAvailSize, pKidMaxElementSize,
|
||||
aState);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it's not our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
if ((kidSize.height > aState.availSize.height) && (kidFrame != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
|
||||
// Since we are giving the next-in-flow our last child, we
|
||||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// give it our original mLastContentIsComplete too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
if (PR_TRUE==gsDebug) printf ("ReflowMappedChildren: calling PushChildren\n");
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
PushChildren(kidFrame, prevKidFrame, originalLastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child after taking into account it's margin
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
if (PR_TRUE==gsDebug) printf ("ReflowMappedChildren: calling PlaceChild\n");
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
|
@ -491,21 +494,26 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
// Special handling for incomplete children
|
||||
// Is the child complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
// No, the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Insert the frame. We'll reflow it next pass through the loop
|
||||
// Add the continuing frame to the sibling list
|
||||
nsIFrame* nextSib = kidFrame->GetNextSibling();
|
||||
continuingFrame->SetNextSibling(nextSib);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
@ -516,10 +524,19 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
|
@ -566,9 +583,9 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
PRBool nsTableOuterFrame::PullUpChildren( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -591,14 +608,13 @@ PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableOuterFrame* nextInFlow = (nsTableOuterFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableOuterFrame* nextInFlow = (nsTableOuterFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -606,127 +622,123 @@ PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableOuterFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
SetReflowState(aState, kidFrame);
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize,
|
||||
aState);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
//NS_ABORT();
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableOuterFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetWidth() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize, aState);
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Place the child after taking into account it's margin
|
||||
// aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
// kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -1163,6 +1175,79 @@ void nsTableOuterFrame::VerifyTree() const
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
|
||||
* pointers.
|
||||
*
|
||||
* Updates the child count and content offsets of all containers that are
|
||||
* affected
|
||||
*
|
||||
* Overloaded here because nsContainerFrame makes assumptions about pseudo-frames
|
||||
* that are not true for tables.
|
||||
*
|
||||
* @param aChild child this child's next-in-flow
|
||||
* @return PR_TRUE if successful and PR_FALSE otherwise
|
||||
*/
|
||||
PRBool nsTableOuterFrame::DeleteChildsNextInFlow(nsIFrame* aChild)
|
||||
{
|
||||
NS_PRECONDITION(aChild->GetGeometricParent() == (nsIFrame*)this, "bad geometric parent");
|
||||
NS_PRECONDITION(nsnull != aChild->GetNextInFlow(), "null next-in-flow");
|
||||
|
||||
nsIFrame* nextInFlow = aChild->GetNextInFlow();
|
||||
nsTableOuterFrame* parent = (nsTableOuterFrame*)nextInFlow->GetGeometricParent();
|
||||
|
||||
// If the next-in-flow has a next-in-flow then delete it too (and
|
||||
// delete it first).
|
||||
if (nsnull != nextInFlow->GetNextInFlow()) {
|
||||
parent->DeleteChildsNextInFlow(nextInFlow);
|
||||
}
|
||||
|
||||
NS_ASSERTION((0 == nextInFlow->ChildCount()) &&
|
||||
(nsnull == nextInFlow->FirstChild()),
|
||||
"deleting !empty next-in-flow");
|
||||
|
||||
// Disconnect the next-in-flow from the flow list
|
||||
nextInFlow->BreakFromPrevFlow();
|
||||
|
||||
// Take the next-in-flow out of the parent's child list
|
||||
if (parent->mFirstChild == nextInFlow) {
|
||||
parent->mFirstChild = nextInFlow->GetNextSibling();
|
||||
if (nsnull != parent->mFirstChild) {
|
||||
parent->SetFirstContentOffset(parent->mFirstChild);
|
||||
if (parent->IsPseudoFrame()) {
|
||||
parent->PropagateContentOffsets();
|
||||
}
|
||||
}
|
||||
|
||||
// When a parent loses it's last child and that last child is a
|
||||
// pseudo-frame then the parent's content offsets are now wrong.
|
||||
// However, we know that the parent will eventually be reflowed
|
||||
// in one of two ways: it will either get a chance to pullup
|
||||
// children or it will be deleted because it's prev-in-flow
|
||||
// (e.g. this) is complete. In either case, the content offsets
|
||||
// will be repaired.
|
||||
|
||||
} else {
|
||||
// Because the next-in-flow is not the first child of the parent
|
||||
// we know that it shares a parent with aChild. Therefore, we need
|
||||
// to capture the next-in-flow's next sibling (in case the
|
||||
// next-in-flow is the last next-in-flow for aChild AND the
|
||||
// next-in-flow is not the last child in parent)
|
||||
NS_ASSERTION(aChild->GetGeometricParent() == parent, "screwy flow");
|
||||
NS_ASSERTION(aChild->GetNextSibling() == nextInFlow, "unexpected sibling");
|
||||
|
||||
aChild->SetNextSibling(nextInFlow->GetNextSibling());
|
||||
}
|
||||
|
||||
// Delete the next-in-flow frame and adjust it's parent's child count
|
||||
nextInFlow->DeleteFrame();
|
||||
parent->mChildCount--;
|
||||
|
||||
NS_POSTCONDITION(nsnull == aChild->GetNextInFlow(), "non null next-in-flow");
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void nsTableOuterFrame::CreateInnerTableFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
// Do we have a prev-in-flow?
|
||||
|
|
|
@ -162,11 +162,9 @@ protected:
|
|||
OuterTableReflowState& aState,
|
||||
nsStyleMolecule* aKidMol);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
void PlaceChild( OuterTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
@ -216,6 +214,21 @@ protected:
|
|||
nsIFrame* aParent,
|
||||
nsTableOuterFrame* aContFrame);
|
||||
|
||||
/**
|
||||
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
|
||||
* pointers.
|
||||
*
|
||||
* Updates the child count and content offsets of all containers that are
|
||||
* affected
|
||||
*
|
||||
* Overloaded here because nsContainerFrame makes assumptions about pseudo-frames
|
||||
* that are not true for tables.
|
||||
*
|
||||
* @param aChild child this child's next-in-flow
|
||||
* @return PR_TRUE if successful and PR_FALSE otherwise
|
||||
*/
|
||||
PRBool nsTableOuterFrame::DeleteChildsNextInFlow(nsIFrame* aChild);
|
||||
|
||||
/** create the inner table frame (nsTableFrame)
|
||||
* handles initial creation as well as creation of continuing frames
|
||||
*/
|
||||
|
|
|
@ -154,6 +154,7 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
nsSize availSize(aMaxSize);
|
||||
nsSize maxSize(0, 0);
|
||||
nsSize kidMaxSize(0,0);
|
||||
nsSize kidMaxElementSize(0,0);
|
||||
nsReflowMetrics kidSize;
|
||||
nscoord cellXOffset = 0;
|
||||
nscoord maxAscent = 0;
|
||||
|
@ -234,9 +235,21 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
if (kidSize.width > maxSize.width) {
|
||||
maxSize.width = kidSize.width;
|
||||
}
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height)) {
|
||||
maxSize.height = kidSize.height;
|
||||
if (NS_UNCONSTRAINEDSIZE==aMaxSize.height)
|
||||
{
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height))
|
||||
maxSize.height = kidSize.height;
|
||||
if (kidMaxSize.height > kidMaxElementSize.height)
|
||||
kidMaxElementSize.height = kidMaxSize.height;
|
||||
}
|
||||
else
|
||||
{ // in the constrained height case, our maxElementSize is the height of our tallest cell
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height))
|
||||
maxSize.height = kidSize.height;
|
||||
if (maxSize.height > kidMaxElementSize.height)
|
||||
kidMaxElementSize.height = maxSize.height;
|
||||
}
|
||||
kidMaxElementSize.width += kidMaxSize.width;
|
||||
if (NS_UNCONSTRAINEDSIZE!=cellXOffset)
|
||||
cellXOffset+=kidSize.width;
|
||||
if (cellXOffset<=0)
|
||||
|
@ -265,6 +278,11 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
if (nsnull != prevKidFrame) {
|
||||
if (LastChild()!=prevKidFrame)
|
||||
{
|
||||
nsIFrame * frame = LastChild();
|
||||
GetGeometricParent()->List();
|
||||
}
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
|
@ -275,7 +293,7 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.ascent = maxAscent;
|
||||
aDesiredSize.descent = maxDescent;
|
||||
if (nsnull != aMaxElementSize) {
|
||||
*aMaxElementSize = kidMaxSize;
|
||||
*aMaxElementSize = kidMaxElementSize;
|
||||
}
|
||||
SetMaxChildHeight(maxCellHeight); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
|
@ -295,6 +313,10 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
result==frComplete?"Complete":"Not Complete",
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
// testing...
|
||||
result = frComplete;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "nsIView.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug1 = PR_FALSE;
|
||||
static PRBool gsDebug1 = PR_TRUE;
|
||||
static PRBool gsDebug2 = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
|
@ -174,13 +174,12 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
|||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowGroupFrame::PlaceChild(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
// Place and size the child
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
@ -276,13 +275,9 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
|
@ -299,6 +294,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
|
@ -311,7 +307,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
|
@ -320,6 +316,9 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
|
@ -333,6 +332,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
|
@ -350,22 +350,27 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
}
|
||||
|
||||
// Update the child count
|
||||
mChildCount = childCount;
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
|
||||
// Set the last content offset based on the last child we mapped.
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
NS_POSTCONDITION(LastChild()->GetIndexInParent() == mLastContentOffset, "bad last content offset");
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -425,14 +430,13 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -440,130 +444,123 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableRowGroupFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
// NS_ABORT();
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableRowGroupFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetHeight() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
/* Row groups should not create continuing frames for rows
|
||||
* unless they absolutely have to!
|
||||
* check to see if this is absolutely necessary (with new params from troy)
|
||||
* otherwise PushChildren and bail, as above.
|
||||
*/
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -592,10 +589,9 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pullup %sok (childCount=%d) [%d,%d,%c]\n",
|
||||
|
@ -651,7 +647,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
// Place our children, one at a time, until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
|
@ -682,9 +678,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
//nsBlockFrame* pseudoFrame = nsnull;
|
||||
nsIFrame* kidFrame;
|
||||
ReflowStatus status;
|
||||
|
||||
// Create a child frame
|
||||
if (nsnull == kidPrevInFlow) {
|
||||
|
@ -696,146 +690,67 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
} else {
|
||||
kidFrame = kidPrevInFlow->CreateContinuingFrame(aPresContext, this);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Link the child frame into the list of children and update the
|
||||
// child count
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status = ReflowChild(kidFrame,aPresContext, kidSize,
|
||||
aState.availSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child. Add the frame to our overflow list
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
mOverflowList = kidFrame;
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Link child frame into the list of children
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(nsnull == prevKidFrame->GetNextSibling(), "bad append");
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
} else {
|
||||
NS_ASSERTION(nsnull == mFirstChild, "bad create");
|
||||
mFirstChild = kidFrame;
|
||||
mFirstChild = kidFrame; // our first child
|
||||
SetFirstContentOffset(kidFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
|
||||
do {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics desiredSize;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing
|
||||
if (kidAvailSize.height > 0) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((nsnull != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height))) {
|
||||
// The child's height is too big to fit in our remaining
|
||||
// space, and it's not our first child.
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
NS_ASSERTION(nsnull == mNextInFlow, "whoops");
|
||||
|
||||
// Chop off the part of our child list that's being overflowed
|
||||
NS_ASSERTION(prevKidFrame->GetNextSibling() == kidFrame, "bad list");
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
|
||||
// Create overflow list
|
||||
mOverflowList = kidFrame;
|
||||
|
||||
// Fixup child count by subtracting off the number of children
|
||||
// that just ended up on the reflow list.
|
||||
PRInt32 overflowKids = 0;
|
||||
nsIFrame* f = kidFrame;
|
||||
while (nsnull != f) {
|
||||
overflowKids++;
|
||||
f = f->GetNextSibling();
|
||||
}
|
||||
mChildCount -= overflowKids;
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
topMargin = 0;
|
||||
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// Child didn't complete so create a continuing frame
|
||||
kidPrevInFlow = kidFrame;
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
|
||||
/*
|
||||
if (nsnull != pseudoFrame) {
|
||||
pseudoFrame = (nsBlockFrame*) kidFrame;
|
||||
}
|
||||
*/
|
||||
// XXX We probably shouldn't assume that there is no room for
|
||||
// the continuation
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
|
||||
prevKidFrame = kidFrame;
|
||||
kidPrevInFlow = nsnull;
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
|
||||
// Update the kidIndex
|
||||
/*
|
||||
if (nsnull != pseudoFrame) {
|
||||
// Adjust kidIndex to reflect the number of children mapped by
|
||||
// the pseudo frame
|
||||
kidIndex = pseudoFrame->NextChildOffset();
|
||||
} else {
|
||||
*/
|
||||
kidIndex++;
|
||||
/*
|
||||
// Did the child complete?
|
||||
if (frNotComplete == status) {
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space
|
||||
mLastContentIsComplete = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
kidPrevInFlow = nsnull;
|
||||
}
|
||||
|
||||
done:
|
||||
// Update the content mapping
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
if (0 != mChildCount) {
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
#endif
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** Layout the entire row group.
|
||||
* This method stacks rows vertically according to HTML 4.0 rules.
|
||||
* Rows are responsible for layout of their children.
|
||||
|
@ -880,15 +795,14 @@ nsTableRowGroupFrame::ResizeReflow( nsIPresContext* aPresContext,
|
|||
// Did we successfully relow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = ReflowUnmappedChildren(aPresContext, state, aMaxElementSize);
|
||||
|
|
|
@ -107,7 +107,6 @@ protected:
|
|||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
|
|
@ -466,7 +466,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflow( nsIPresContext* aPresContext,
|
|||
PRIntervalTime startTime = PR_IntervalNow();
|
||||
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf ("*** tableframe reflow\t\t%d\n", this);
|
||||
printf ("*** tableframe reflow\t\t%p\n", this);
|
||||
|
||||
if (PR_TRUE==NeedsReflow(aMaxSize))
|
||||
{
|
||||
|
@ -730,15 +730,14 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
|
|||
// Did we successfully reflow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = ReflowUnmappedChildren(aPresContext, state, aMaxElementSize);
|
||||
|
@ -822,7 +821,6 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
InnerTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
|
@ -889,7 +887,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
// having to push children, we have the correct value to hand to
|
||||
// PushChildren.
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
@ -921,32 +919,22 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it's not our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
|
||||
// Since we are giving the next-in-flow our last child, we
|
||||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// give it our original mLastContentIsComplete too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
PushChildren(kidFrame, prevKidFrame, originalLastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -956,8 +944,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
|
@ -965,21 +952,24 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
// Special handling for incomplete children
|
||||
if (frNotComplete == status) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Insert the frame. We'll reflow it next pass through the loop
|
||||
// Add the continuing frame to the sibling list
|
||||
nsIFrame* nextSib = kidFrame->GetNextSibling();
|
||||
continuingFrame->SetNextSibling(nextSib);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
@ -990,11 +980,19 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
|
@ -1003,10 +1001,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
// Update the child count
|
||||
mChildCount = childCount;
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
|
||||
// Set the last content offset based on the last child we mapped.
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
NS_POSTCONDITION(LastChild()->GetIndexInParent() == mLastContentOffset, "bad last content offset");
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -1042,8 +1037,8 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
|||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -1066,14 +1061,13 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableFrame* nextInFlow = (nsTableFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableFrame* nextInFlow = (nsTableFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -1081,125 +1075,127 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetHeight() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -1228,28 +1224,7 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pullup %sok (childCount=%d) [%d,%d,%c]\n",
|
||||
(result ? "" : "NOT "),
|
||||
mChildCount,
|
||||
mFirstContentOffset, mLastContentOffset,
|
||||
(mLastContentIsComplete ? 'T' : 'F'));
|
||||
#ifdef NOISY_FLOW
|
||||
{
|
||||
nsTableFrame* flow = (nsTableFrame*) mNextInFlow;
|
||||
while (flow != 0) {
|
||||
printf(" %p: [%d,%d,%c]\n",
|
||||
flow, flow->mFirstContentOffset, flow->mLastContentOffset,
|
||||
(flow->mLastContentIsComplete ? 'T' : 'F'));
|
||||
flow = (nsTableFrame*) flow->mNextInFlow;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -1270,8 +1245,8 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
nsIFrame* kidPrevInFlow = nsnull;
|
||||
ReflowStatus result = frNotComplete;
|
||||
nsIFrame* kidPrevInFlow = nsnull;
|
||||
ReflowStatus result = frNotComplete;
|
||||
|
||||
// If we have no children and we have a prev-in-flow then we need to pick
|
||||
// up where it left off. If we have children, e.g. we're being resized, then
|
||||
|
@ -1286,14 +1261,13 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidPrevInFlow = prev->LastChild();
|
||||
}
|
||||
}
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Place our children, one at a time, until we are out of children
|
||||
// Place our children, one at a time until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
nsIFrame* prevKidFrame = LastChild(); // XXX remember this...
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
for (;;) {
|
||||
// Get the next content object
|
||||
|
@ -1310,16 +1284,14 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
|
||||
// Resolve style
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* kidStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(kid, this);
|
||||
|
||||
// Figure out how we should treat the child
|
||||
nsIFrame* kidFrame;
|
||||
nsStyleMolecule* kidMol =
|
||||
(nsStyleMolecule*)kidStyleContext->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
nsIFrame* kidFrame;
|
||||
ReflowStatus status;
|
||||
|
||||
// Create a child frame
|
||||
if (nsnull == kidPrevInFlow) {
|
||||
|
@ -1331,131 +1303,72 @@ nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
} else {
|
||||
kidFrame = kidPrevInFlow->CreateContinuingFrame(aPresContext, this);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Link the child frame into the list of children and update the
|
||||
// child count
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status = ReflowChild(kidFrame,aPresContext, kidSize,
|
||||
aState.availSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child. Add the frame to our overflow list
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
mOverflowList = kidFrame;
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Link child frame into the list of children
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(nsnull == prevKidFrame->GetNextSibling(), "bad append");
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
} else {
|
||||
NS_ASSERTION(nsnull == mFirstChild, "bad create");
|
||||
mFirstChild = kidFrame;
|
||||
mFirstChild = kidFrame; // our first child
|
||||
SetFirstContentOffset(kidFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
|
||||
do {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics desiredSize;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing
|
||||
if (kidAvailSize.height > 0) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((nsnull != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height))) {
|
||||
// The child's height is too big to fit in our remaining
|
||||
// space, and it's not our first child.
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
NS_ASSERTION(nsnull == mNextInFlow, "whoops");
|
||||
|
||||
// Chop off the part of our child list that's being overflowed
|
||||
NS_ASSERTION(prevKidFrame->GetNextSibling() == kidFrame, "bad list");
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
|
||||
// Create overflow list
|
||||
mOverflowList = kidFrame;
|
||||
|
||||
// Fixup child count by subtracting off the number of children
|
||||
// that just ended up on the reflow list.
|
||||
PRInt32 overflowKids = 0;
|
||||
nsIFrame* f = kidFrame;
|
||||
while (nsnull != f) {
|
||||
overflowKids++;
|
||||
f = f->GetNextSibling();
|
||||
}
|
||||
mChildCount -= overflowKids;
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
topMargin = 0;
|
||||
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// Child didn't complete so create a continuing frame
|
||||
kidPrevInFlow = kidFrame;
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
|
||||
// XXX We probably shouldn't assume that there is no room for
|
||||
// the continuation
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
|
||||
prevKidFrame = kidFrame;
|
||||
kidPrevInFlow = nsnull;
|
||||
|
||||
// Update the kidIndex
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
|
||||
// Did the child complete?
|
||||
if (frNotComplete == status) {
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space
|
||||
mLastContentIsComplete = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
kidPrevInFlow = nsnull;
|
||||
}
|
||||
|
||||
done:
|
||||
// Update the content mapping
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
if (0 != mChildCount) {
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
#endif
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Now I've got all the cells laid out in an infinite space.
|
||||
For each column, use the min size for each cell in that column
|
||||
|
@ -2254,6 +2167,7 @@ nsVoidArray * nsTableFrame::GetColumnLayoutData()
|
|||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
NS_ASSERTION(nsnull!=firstInFlow->mColumnLayoutData, "illegal state -- no column layout data");
|
||||
return firstInFlow->mColumnLayoutData;
|
||||
}
|
||||
|
||||
|
@ -2463,9 +2377,18 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
|
|||
else
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state");
|
||||
#ifdef DEBUG
|
||||
nsVoidArray *cld = GetColumnLayoutData();
|
||||
NS_ASSERTION(nsnull!=cld, "no column layout data");
|
||||
PRInt32 numCols = cld->Count();
|
||||
NS_ASSERTION (numCols > aColIndex, "bad arg, col index out of bounds");
|
||||
#endif
|
||||
if (nsnull!=mColumnWidths)
|
||||
result = mColumnWidths[aColIndex];
|
||||
}
|
||||
|
||||
//printf("GET_COL_WIDTH: %p, FIF=%p getting col %d and returning %d\n", this, firstInFlow, aColIndex, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2473,6 +2396,7 @@ void nsTableFrame::SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth)
|
|||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
//printf("SET_COL_WIDTH: %p, FIF=%p setting col %d to %d\n", this, firstInFlow, aColIndex, aWidth);
|
||||
if (this!=firstInFlow)
|
||||
firstInFlow->SetColumnWidth(aColIndex, aWidth);
|
||||
else
|
||||
|
|
|
@ -223,7 +223,6 @@ protected:
|
|||
InnerTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
|||
|
||||
struct OuterTableReflowState {
|
||||
|
||||
// The presentation context
|
||||
nsIPresContext *pc;
|
||||
|
||||
// The body's style molecule
|
||||
nsStyleMolecule* mol;
|
||||
|
||||
|
@ -74,6 +77,7 @@ struct OuterTableReflowState {
|
|||
const nsSize& aMaxSize,
|
||||
nsStyleMolecule* aMol)
|
||||
{
|
||||
pc = aPresContext;
|
||||
mol = aMol;
|
||||
availSize.width = aMaxSize.width;
|
||||
availSize.height = aMaxSize.height;
|
||||
|
@ -254,19 +258,18 @@ nsIFrame::ReflowStatus nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresCont
|
|||
// Did we successfully relow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// nothing to do, we will never have unmapped children!
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
NS_ABORT(); // huge error for tables!
|
||||
} else {
|
||||
// We were unable to pull-up all the existing frames from the
|
||||
// next in flow
|
||||
// We were unable to pull-up all the existing frames from the next in flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +306,18 @@ nsIFrame::ReflowStatus nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresCont
|
|||
// replace with a check that does not assume linear placement of children
|
||||
// PostReflowCheck(status);
|
||||
#endif
|
||||
// REMOVE ME!
|
||||
/*
|
||||
nsIFrame *next = this;
|
||||
nsIFrame *root=nsnull;
|
||||
while (nsnull!=next)
|
||||
{
|
||||
root = next;
|
||||
next = next->GetGeometricParent();
|
||||
}
|
||||
root->List();
|
||||
*/
|
||||
// end REMOVE ME!
|
||||
|
||||
return status;
|
||||
|
||||
|
@ -332,11 +347,9 @@ nscoord nsTableOuterFrame::GetTopMarginFor(nsIPresContext* aCX,
|
|||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableOuterFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
void nsTableOuterFrame::PlaceChild( OuterTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
|
@ -411,7 +424,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
// having to push children, we have the correct value to hand to
|
||||
// PushChildren.
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
@ -419,7 +432,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
nsSize kidAvailSize(aState.innerTableMaxSize.width, aState.availSize.height);
|
||||
nsReflowMetrics desiredSize;
|
||||
nsReflowMetrics kidSize;
|
||||
nsIFrame::ReflowStatus status;
|
||||
|
||||
SetReflowState(aState, kidFrame);
|
||||
|
@ -448,42 +461,32 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize,
|
||||
kidAvailSize, pKidMaxElementSize,
|
||||
aState);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it's not our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
if ((kidSize.height > aState.availSize.height) && (kidFrame != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
|
||||
// Since we are giving the next-in-flow our last child, we
|
||||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// give it our original mLastContentIsComplete too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
if (PR_TRUE==gsDebug) printf ("ReflowMappedChildren: calling PushChildren\n");
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
PushChildren(kidFrame, prevKidFrame, originalLastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child after taking into account it's margin
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
if (PR_TRUE==gsDebug) printf ("ReflowMappedChildren: calling PlaceChild\n");
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
|
@ -491,21 +494,26 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
// Special handling for incomplete children
|
||||
// Is the child complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
// No, the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Insert the frame. We'll reflow it next pass through the loop
|
||||
// Add the continuing frame to the sibling list
|
||||
nsIFrame* nextSib = kidFrame->GetNextSibling();
|
||||
continuingFrame->SetNextSibling(nextSib);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
@ -516,10 +524,19 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
|
@ -566,9 +583,9 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
|
|||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
PRBool nsTableOuterFrame::PullUpChildren( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -591,14 +608,13 @@ PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableOuterFrame* nextInFlow = (nsTableOuterFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableOuterFrame* nextInFlow = (nsTableOuterFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -606,127 +622,123 @@ PRBool nsTableOuterFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableOuterFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
SetReflowState(aState, kidFrame);
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize,
|
||||
aState);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
//NS_ABORT();
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableOuterFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetWidth() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize, aState);
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Place the child after taking into account it's margin
|
||||
// aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
// kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -1163,6 +1175,79 @@ void nsTableOuterFrame::VerifyTree() const
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
|
||||
* pointers.
|
||||
*
|
||||
* Updates the child count and content offsets of all containers that are
|
||||
* affected
|
||||
*
|
||||
* Overloaded here because nsContainerFrame makes assumptions about pseudo-frames
|
||||
* that are not true for tables.
|
||||
*
|
||||
* @param aChild child this child's next-in-flow
|
||||
* @return PR_TRUE if successful and PR_FALSE otherwise
|
||||
*/
|
||||
PRBool nsTableOuterFrame::DeleteChildsNextInFlow(nsIFrame* aChild)
|
||||
{
|
||||
NS_PRECONDITION(aChild->GetGeometricParent() == (nsIFrame*)this, "bad geometric parent");
|
||||
NS_PRECONDITION(nsnull != aChild->GetNextInFlow(), "null next-in-flow");
|
||||
|
||||
nsIFrame* nextInFlow = aChild->GetNextInFlow();
|
||||
nsTableOuterFrame* parent = (nsTableOuterFrame*)nextInFlow->GetGeometricParent();
|
||||
|
||||
// If the next-in-flow has a next-in-flow then delete it too (and
|
||||
// delete it first).
|
||||
if (nsnull != nextInFlow->GetNextInFlow()) {
|
||||
parent->DeleteChildsNextInFlow(nextInFlow);
|
||||
}
|
||||
|
||||
NS_ASSERTION((0 == nextInFlow->ChildCount()) &&
|
||||
(nsnull == nextInFlow->FirstChild()),
|
||||
"deleting !empty next-in-flow");
|
||||
|
||||
// Disconnect the next-in-flow from the flow list
|
||||
nextInFlow->BreakFromPrevFlow();
|
||||
|
||||
// Take the next-in-flow out of the parent's child list
|
||||
if (parent->mFirstChild == nextInFlow) {
|
||||
parent->mFirstChild = nextInFlow->GetNextSibling();
|
||||
if (nsnull != parent->mFirstChild) {
|
||||
parent->SetFirstContentOffset(parent->mFirstChild);
|
||||
if (parent->IsPseudoFrame()) {
|
||||
parent->PropagateContentOffsets();
|
||||
}
|
||||
}
|
||||
|
||||
// When a parent loses it's last child and that last child is a
|
||||
// pseudo-frame then the parent's content offsets are now wrong.
|
||||
// However, we know that the parent will eventually be reflowed
|
||||
// in one of two ways: it will either get a chance to pullup
|
||||
// children or it will be deleted because it's prev-in-flow
|
||||
// (e.g. this) is complete. In either case, the content offsets
|
||||
// will be repaired.
|
||||
|
||||
} else {
|
||||
// Because the next-in-flow is not the first child of the parent
|
||||
// we know that it shares a parent with aChild. Therefore, we need
|
||||
// to capture the next-in-flow's next sibling (in case the
|
||||
// next-in-flow is the last next-in-flow for aChild AND the
|
||||
// next-in-flow is not the last child in parent)
|
||||
NS_ASSERTION(aChild->GetGeometricParent() == parent, "screwy flow");
|
||||
NS_ASSERTION(aChild->GetNextSibling() == nextInFlow, "unexpected sibling");
|
||||
|
||||
aChild->SetNextSibling(nextInFlow->GetNextSibling());
|
||||
}
|
||||
|
||||
// Delete the next-in-flow frame and adjust it's parent's child count
|
||||
nextInFlow->DeleteFrame();
|
||||
parent->mChildCount--;
|
||||
|
||||
NS_POSTCONDITION(nsnull == aChild->GetNextInFlow(), "non null next-in-flow");
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void nsTableOuterFrame::CreateInnerTableFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
// Do we have a prev-in-flow?
|
||||
|
|
|
@ -162,11 +162,9 @@ protected:
|
|||
OuterTableReflowState& aState,
|
||||
nsStyleMolecule* aKidMol);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
OuterTableReflowState& aState,
|
||||
void PlaceChild( OuterTableReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
@ -216,6 +214,21 @@ protected:
|
|||
nsIFrame* aParent,
|
||||
nsTableOuterFrame* aContFrame);
|
||||
|
||||
/**
|
||||
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
|
||||
* pointers.
|
||||
*
|
||||
* Updates the child count and content offsets of all containers that are
|
||||
* affected
|
||||
*
|
||||
* Overloaded here because nsContainerFrame makes assumptions about pseudo-frames
|
||||
* that are not true for tables.
|
||||
*
|
||||
* @param aChild child this child's next-in-flow
|
||||
* @return PR_TRUE if successful and PR_FALSE otherwise
|
||||
*/
|
||||
PRBool nsTableOuterFrame::DeleteChildsNextInFlow(nsIFrame* aChild);
|
||||
|
||||
/** create the inner table frame (nsTableFrame)
|
||||
* handles initial creation as well as creation of continuing frames
|
||||
*/
|
||||
|
|
|
@ -154,6 +154,7 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
nsSize availSize(aMaxSize);
|
||||
nsSize maxSize(0, 0);
|
||||
nsSize kidMaxSize(0,0);
|
||||
nsSize kidMaxElementSize(0,0);
|
||||
nsReflowMetrics kidSize;
|
||||
nscoord cellXOffset = 0;
|
||||
nscoord maxAscent = 0;
|
||||
|
@ -234,9 +235,21 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
if (kidSize.width > maxSize.width) {
|
||||
maxSize.width = kidSize.width;
|
||||
}
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height)) {
|
||||
maxSize.height = kidSize.height;
|
||||
if (NS_UNCONSTRAINEDSIZE==aMaxSize.height)
|
||||
{
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height))
|
||||
maxSize.height = kidSize.height;
|
||||
if (kidMaxSize.height > kidMaxElementSize.height)
|
||||
kidMaxElementSize.height = kidMaxSize.height;
|
||||
}
|
||||
else
|
||||
{ // in the constrained height case, our maxElementSize is the height of our tallest cell
|
||||
if ((1==rowSpan) && (kidSize.height > maxSize.height))
|
||||
maxSize.height = kidSize.height;
|
||||
if (maxSize.height > kidMaxElementSize.height)
|
||||
kidMaxElementSize.height = maxSize.height;
|
||||
}
|
||||
kidMaxElementSize.width += kidMaxSize.width;
|
||||
if (NS_UNCONSTRAINEDSIZE!=cellXOffset)
|
||||
cellXOffset+=kidSize.width;
|
||||
if (cellXOffset<=0)
|
||||
|
@ -265,6 +278,11 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
if (nsnull != prevKidFrame) {
|
||||
if (LastChild()!=prevKidFrame)
|
||||
{
|
||||
nsIFrame * frame = LastChild();
|
||||
GetGeometricParent()->List();
|
||||
}
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
|
@ -275,7 +293,7 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.ascent = maxAscent;
|
||||
aDesiredSize.descent = maxDescent;
|
||||
if (nsnull != aMaxElementSize) {
|
||||
*aMaxElementSize = kidMaxSize;
|
||||
*aMaxElementSize = kidMaxElementSize;
|
||||
}
|
||||
SetMaxChildHeight(maxCellHeight); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
|
@ -295,6 +313,10 @@ nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
result==frComplete?"Complete":"Not Complete",
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
// testing...
|
||||
result = frComplete;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "nsIView.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug1 = PR_FALSE;
|
||||
static PRBool gsDebug1 = PR_TRUE;
|
||||
static PRBool gsDebug2 = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
|
@ -174,13 +174,12 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
|||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowGroupFrame::PlaceChild(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
// Place and size the child
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
@ -276,13 +275,9 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
// Reflow the child into the available space
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
|
@ -299,6 +294,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
// give it our original mLastContentIsComplete, too (in case we
|
||||
// are pushing into an empty next-in-flow)
|
||||
PushChildren(kidFrame, prevKidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
||||
// Our mLastContentIsComplete was already set by the last kid we
|
||||
// reflowed reflow's status
|
||||
|
@ -311,7 +307,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
|
@ -320,6 +316,9 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
}
|
||||
childCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Update mLastContentIsComplete now that this kid fits
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
|
||||
|
@ -333,6 +332,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
PRBool lastContentIsComplete = mLastContentIsComplete;
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// No the child isn't complete, and it doesn't have a next in flow so
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
|
@ -350,22 +350,27 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
|||
lastContentIsComplete = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
nsIFrame* nextSibling = kidFrame->GetNextSibling();
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
|
||||
// XXX talk with troy about checking for available space here
|
||||
}
|
||||
|
||||
// Update the child count
|
||||
mChildCount = childCount;
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
|
||||
// Set the last content offset based on the last child we mapped.
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "unexpected last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
NS_POSTCONDITION(LengthOf(mFirstChild) == mChildCount, "bad child count");
|
||||
NS_POSTCONDITION(LastChild()->GetIndexInParent() == mLastContentOffset, "bad last content offset");
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
|
@ -425,14 +430,13 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mNextInFlow, "null next-in-flow");
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
|
||||
// The frame previous to the current frame we are reflowing. This
|
||||
// starts out initially as our last frame.
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 kidIndex = NextChildOffset();
|
||||
#endif
|
||||
nsIFrame* prevKidFrame = LastChild();
|
||||
|
||||
// This will hold the prevKidFrame's mLastContentIsComplete
|
||||
// status. If we have to push the frame that follows prevKidFrame
|
||||
|
@ -440,130 +444,123 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prevKidFrame is initially our last frame, it's completion status
|
||||
// is our mLastContentIsComplete value.
|
||||
PRBool prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsReflowMetrics desiredSize;
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
// Get first available frame from the next-in-flow
|
||||
nsIFrame* kidFrame = PullUpOneChild(nextInFlow, prevKidFrame);
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
|
||||
// Any more child frames?
|
||||
if (nsnull == kidFrame) {
|
||||
// We've pulled up all the children from that next-in-flow, so
|
||||
// move to the next next-in-flow.
|
||||
nextInFlow = (nsTableRowGroupFrame*) nextInFlow->mNextInFlow;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContent* kid = kidFrame->GetContent();
|
||||
nsIStyleContext* kidSC = kidFrame->GetStyleContext(aPresContext);
|
||||
nsStyleMolecule* kidMol = (nsStyleMolecule*)kidSC->GetData(kStyleMoleculeSID);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
ReflowStatus status;
|
||||
do {
|
||||
// Only skip the reflow if this is not our first child and we are
|
||||
// out of space.
|
||||
if ((kidFrame == mFirstChild) || (kidAvailSize.height > 0)) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height)))
|
||||
{
|
||||
// The child's height is too big to fit at all in our remaining space,
|
||||
// and it wouldn't have been our first child.
|
||||
//
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PRBool lastComplete = PRBool(nsnull == kidFrame->GetNextInFlow());
|
||||
PushChildren(kidFrame, prevKidFrame, lastComplete);
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
mChildCount--;
|
||||
result = PR_FALSE;
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
goto push_done;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
// No. Any frames on its overflow list?
|
||||
if (nsnull != nextInFlow->mOverflowList) {
|
||||
// Move the overflow list to become the child list
|
||||
// NS_ABORT();
|
||||
nextInFlow->AppendChildren(nextInFlow->mOverflowList);
|
||||
nextInFlow->mOverflowList = nsnull;
|
||||
kidFrame = nextInFlow->mFirstChild;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
// We've pulled up all the children, so move to the next-in-flow.
|
||||
nextInFlow = (nsTableRowGroupFrame*)nextInFlow->GetNextInFlow();
|
||||
continue;
|
||||
}
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pulled up ");
|
||||
((nsFrame*)kidFrame)->ListTag(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
// See if the child fits in the available space. If it fits or
|
||||
// it's splittable then reflow it. The reason we can't just move
|
||||
// it is that we still need ascent/descent information
|
||||
if ((kidFrame->GetHeight() > aState.availSize.height) &&
|
||||
!kidFrame->IsSplittable()) {
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
status = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
/* Row groups should not create continuing frames for rows
|
||||
* unless they absolutely have to!
|
||||
* check to see if this is absolutely necessary (with new params from troy)
|
||||
* otherwise PushChildren and bail, as above.
|
||||
*/
|
||||
// Is the child we just pulled up complete?
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete.
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
mLastContentIsComplete = prevLastContentIsComplete;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the continuing frame to our sibling list.
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
} else {
|
||||
// The child has a next-in-flow, but it's not one of ours.
|
||||
// It *must* be in one of our next-in-flows. Collect it
|
||||
// then.
|
||||
NS_ASSERTION(kidNextInFlow->GetGeometricParent() != this,
|
||||
"busted kid next-in-flow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidSC);
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
nextInFlow->mFirstChild = kidFrame->GetNextSibling();
|
||||
nextInFlow->mChildCount--;
|
||||
// Update the next-in-flows first content offset
|
||||
if (nsnull != nextInFlow->mFirstChild) {
|
||||
nextInFlow->SetFirstContentOffset(nextInFlow->mFirstChild);
|
||||
}
|
||||
|
||||
// Link the frame into our list of children
|
||||
kidFrame->SetGeometricParent(this);
|
||||
if (nextInFlow == kidFrame->GetContentParent()) {
|
||||
kidFrame->SetContentParent(this);
|
||||
}
|
||||
if (nsnull == prevKidFrame) {
|
||||
mFirstChild = kidFrame;
|
||||
SetFirstContentOffset(kidFrame);
|
||||
} else {
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
}
|
||||
kidFrame->SetNextSibling(nsnull);
|
||||
mChildCount++;
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
prevKidFrame = kidFrame;
|
||||
prevLastContentIsComplete = mLastContentIsComplete;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a
|
||||
// continuing frame. The creation appends it to the flow and
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
// it to the next-in-flow. This ensures the next-in-flow's
|
||||
// content offsets and child count are set properly. Note that
|
||||
// we can safely assume that the continuation is complete so
|
||||
// we pass PR_TRUE into PushChidren in case our next-in-flow
|
||||
// was just drained and now needs to know it's
|
||||
// mLastContentIsComplete state.
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
|
||||
PushChildren(continuingFrame, kidFrame, PR_TRUE);
|
||||
|
||||
// After we push the continuation frame we don't need to fuss
|
||||
// with mLastContentIsComplete beause the continuation frame
|
||||
// is no longer on *our* list.
|
||||
}
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
push_done:;
|
||||
// Update our last content index
|
||||
// Update our last content offset
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
|
@ -592,10 +589,9 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
|
||||
#ifdef NOISY
|
||||
ListTag(stdout);
|
||||
printf(": pullup %sok (childCount=%d) [%d,%d,%c]\n",
|
||||
|
@ -651,7 +647,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
PRBool originalLastContentIsComplete = mLastContentIsComplete;
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
// Place our children, one at a time, until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
|
@ -682,9 +678,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMol);
|
||||
nscoord bottomMargin = kidMol->margin.bottom;
|
||||
|
||||
//nsBlockFrame* pseudoFrame = nsnull;
|
||||
nsIFrame* kidFrame;
|
||||
ReflowStatus status;
|
||||
|
||||
// Create a child frame
|
||||
if (nsnull == kidPrevInFlow) {
|
||||
|
@ -696,146 +690,67 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
} else {
|
||||
kidFrame = kidPrevInFlow->CreateContinuingFrame(aPresContext, this);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Link the child frame into the list of children and update the
|
||||
// child count
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status = ReflowChild(kidFrame,aPresContext, kidSize,
|
||||
aState.availSize, pKidMaxElementSize);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child. Add the frame to our overflow list
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
mOverflowList = kidFrame;
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Link child frame into the list of children
|
||||
if (nsnull != prevKidFrame) {
|
||||
NS_ASSERTION(nsnull == prevKidFrame->GetNextSibling(), "bad append");
|
||||
prevKidFrame->SetNextSibling(kidFrame);
|
||||
} else {
|
||||
NS_ASSERTION(nsnull == mFirstChild, "bad create");
|
||||
mFirstChild = kidFrame;
|
||||
mFirstChild = kidFrame; // our first child
|
||||
SetFirstContentOffset(kidFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
|
||||
do {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsReflowMetrics desiredSize;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMol->margin.left + kidMol->margin.right;
|
||||
}
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing
|
||||
if (kidAvailSize.height > 0) {
|
||||
status = ReflowChild(kidFrame, aPresContext, desiredSize,
|
||||
kidAvailSize, pKidMaxElementSize);
|
||||
}
|
||||
|
||||
// Did the child fit?
|
||||
if ((nsnull != mFirstChild) &&
|
||||
((kidAvailSize.height <= 0) ||
|
||||
(desiredSize.height > kidAvailSize.height))) {
|
||||
// The child's height is too big to fit in our remaining
|
||||
// space, and it's not our first child.
|
||||
NS_ASSERTION(nsnull == mOverflowList, "bad overflow list");
|
||||
NS_ASSERTION(nsnull == mNextInFlow, "whoops");
|
||||
|
||||
// Chop off the part of our child list that's being overflowed
|
||||
NS_ASSERTION(prevKidFrame->GetNextSibling() == kidFrame, "bad list");
|
||||
prevKidFrame->SetNextSibling(nsnull);
|
||||
|
||||
// Create overflow list
|
||||
mOverflowList = kidFrame;
|
||||
|
||||
// Fixup child count by subtracting off the number of children
|
||||
// that just ended up on the reflow list.
|
||||
PRInt32 overflowKids = 0;
|
||||
nsIFrame* f = kidFrame;
|
||||
while (nsnull != f) {
|
||||
overflowKids++;
|
||||
f = f->GetNextSibling();
|
||||
}
|
||||
mChildCount -= overflowKids;
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Advance y by the topMargin between children. Zero out the
|
||||
// topMargin in case this frame is continued because
|
||||
// continuations do not have a top margin. Update the prev
|
||||
// bottom margin state in the body reflow state so that we can
|
||||
// apply the bottom margin when we hit the next child (or
|
||||
// finish).
|
||||
aState.y += topMargin;
|
||||
nsRect kidRect (0, 0, desiredSize.width, desiredSize.height);
|
||||
kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, kidMol, aMaxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
topMargin = 0;
|
||||
|
||||
mLastContentIsComplete = PRBool(status == frComplete);
|
||||
if (frNotComplete == status) {
|
||||
// Child didn't complete so create a continuing frame
|
||||
kidPrevInFlow = kidFrame;
|
||||
nsIFrame* continuingFrame =
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this);
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
prevKidFrame = kidFrame;
|
||||
kidFrame = continuingFrame;
|
||||
mChildCount++;
|
||||
|
||||
/*
|
||||
if (nsnull != pseudoFrame) {
|
||||
pseudoFrame = (nsBlockFrame*) kidFrame;
|
||||
}
|
||||
*/
|
||||
// XXX We probably shouldn't assume that there is no room for
|
||||
// the continuation
|
||||
}
|
||||
} while (frNotComplete == status);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
|
||||
prevKidFrame = kidFrame;
|
||||
kidPrevInFlow = nsnull;
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
|
||||
// Update the kidIndex
|
||||
/*
|
||||
if (nsnull != pseudoFrame) {
|
||||
// Adjust kidIndex to reflect the number of children mapped by
|
||||
// the pseudo frame
|
||||
kidIndex = pseudoFrame->NextChildOffset();
|
||||
} else {
|
||||
*/
|
||||
kidIndex++;
|
||||
/*
|
||||
// Did the child complete?
|
||||
if (frNotComplete == status) {
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space
|
||||
mLastContentIsComplete = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
kidPrevInFlow = nsnull;
|
||||
}
|
||||
|
||||
done:
|
||||
// Update the content mapping
|
||||
NS_ASSERTION(LastChild() == prevKidFrame, "bad last child");
|
||||
if (0 != mChildCount) {
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
}
|
||||
SetLastContentOffset(prevKidFrame);
|
||||
#ifdef NS_DEBUG
|
||||
PRInt32 len = LengthOf(mFirstChild);
|
||||
NS_ASSERTION(len == mChildCount, "bad child count");
|
||||
#endif
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** Layout the entire row group.
|
||||
* This method stacks rows vertically according to HTML 4.0 rules.
|
||||
* Rows are responsible for layout of their children.
|
||||
|
@ -880,15 +795,14 @@ nsTableRowGroupFrame::ResizeReflow( nsIPresContext* aPresContext,
|
|||
// Did we successfully relow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
// Any space left?
|
||||
if ((nsnull != mFirstChild) && (state.availSize.height <= 0)) {
|
||||
if (state.availSize.height <= 0) {
|
||||
// No space left. Don't try to pull-up children or reflow unmapped
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = frNotComplete;
|
||||
}
|
||||
} else if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if ((nsnull == mNextInFlow) ||
|
||||
PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
if (PullUpChildren(aPresContext, state, aMaxElementSize)) {
|
||||
// If we still have unmapped children then create some new frames
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
status = ReflowUnmappedChildren(aPresContext, state, aMaxElementSize);
|
||||
|
|
|
@ -107,7 +107,6 @@ protected:
|
|||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsStyleMolecule* aKidMol,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче