mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 274516. Tables should use the ordered rowgroup array to decide which children to push, not just follow the sibling list. Also, repeating footers should not be pushed. r=bernd, sr=bzbarsky, a=choffman
This commit is contained in:
parent
344cf0f06e
commit
996d1e3d9e
@ -177,7 +177,7 @@ nsFrameList::AppendFrame(nsIFrame* aParent, nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsFrameList::RemoveFrame(nsIFrame* aFrame)
|
||||
nsFrameList::RemoveFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aFrame, "null ptr");
|
||||
if (nsnull != aFrame) {
|
||||
@ -188,7 +188,10 @@ nsFrameList::RemoveFrame(nsIFrame* aFrame)
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
nsIFrame* prevSibling = GetPrevSiblingFor(aFrame);
|
||||
nsIFrame* prevSibling = aPrevSiblingHint;
|
||||
if (!prevSibling || prevSibling->GetNextSibling() != aFrame) {
|
||||
prevSibling = GetPrevSiblingFor(aFrame);
|
||||
}
|
||||
if (prevSibling) {
|
||||
prevSibling->SetNextSibling(nextFrame);
|
||||
return PR_TRUE;
|
||||
|
@ -79,8 +79,10 @@ public:
|
||||
|
||||
// Take aFrame out of the frame list. This also disconnects aFrame
|
||||
// from the sibling list. This will return PR_FALSE if aFrame is
|
||||
// nsnull or if aFrame is not in the list.
|
||||
PRBool RemoveFrame(nsIFrame* aFrame);
|
||||
// nsnull or if aFrame is not in the list. The second frame is
|
||||
// a hint for the prev-sibling of aFrame; if the hint is correct,
|
||||
// then this is O(1) time.
|
||||
PRBool RemoveFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint = nsnull);
|
||||
|
||||
// Remove the first child from the list. The caller is assumed to be
|
||||
// holding a reference to the first child. This call is equivalent
|
||||
|
@ -2179,15 +2179,27 @@ nsTableFrame::GetFirstBodyRowGroupFrame()
|
||||
// Table specific version that takes into account repeated header and footer
|
||||
// frames when continuing table frames
|
||||
void
|
||||
nsTableFrame::PushChildren(nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling)
|
||||
nsTableFrame::PushChildren(const nsAutoVoidArray& aFrames,
|
||||
PRInt32 aPushFrom)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aFromChild, "null pointer");
|
||||
NS_PRECONDITION(nsnull != aPrevSibling, "pushing first child");
|
||||
NS_PRECONDITION(aPrevSibling->GetNextSibling() == aFromChild, "bad prev sibling");
|
||||
NS_PRECONDITION(aPushFrom > 0, "pushing first child");
|
||||
|
||||
// Disconnect aFromChild from its previous sibling
|
||||
aPrevSibling->SetNextSibling(nsnull);
|
||||
// extract the frames from the array into a sibling list
|
||||
nsFrameList frames;
|
||||
nsIFrame* lastFrame = nsnull;
|
||||
PRUint32 childX;
|
||||
nsIFrame* prevSiblingHint =
|
||||
NS_STATIC_CAST(nsIFrame*, aFrames.ElementAt(aPushFrom - 1));
|
||||
for (childX = aPushFrom; childX < aFrames.Count(); ++childX) {
|
||||
nsIFrame* f = NS_STATIC_CAST(nsIFrame*, aFrames.FastElementAt(childX));
|
||||
// Don't push repeatable frames, do push non-rowgroup frames
|
||||
if (f->GetType() != nsLayoutAtoms::tableRowGroupFrame ||
|
||||
!NS_STATIC_CAST(nsTableRowGroupFrame*, f)->IsRepeatable()) {
|
||||
mFrames.RemoveFrame(f, prevSiblingHint);
|
||||
frames.InsertFrame(nsnull, lastFrame, f);
|
||||
lastFrame = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsnull != mNextInFlow) {
|
||||
nsTableFrame* nextInFlow = (nsTableFrame*)mNextInFlow;
|
||||
@ -2200,14 +2212,14 @@ nsTableFrame::PushChildren(nsIFrame* aFromChild,
|
||||
}
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented.
|
||||
for (nsIFrame* f = aFromChild; f; f = f->GetNextSibling()) {
|
||||
for (nsIFrame* f = frames.FirstChild(); f; f = f->GetNextSibling()) {
|
||||
nsHTMLContainerFrame::ReparentFrameView(GetPresContext(), f, this, nextInFlow);
|
||||
}
|
||||
nextInFlow->mFrames.InsertFrames(mNextInFlow, prevSibling, aFromChild);
|
||||
nextInFlow->mFrames.InsertFrames(mNextInFlow, prevSibling, frames.FirstChild());
|
||||
}
|
||||
else {
|
||||
// Add the frames to our overflow list
|
||||
SetOverflowFrames(GetPresContext(), aFromChild);
|
||||
SetOverflowFrames(GetPresContext(), frames.FirstChild());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3146,7 +3158,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
|
||||
if (doReflowChild) {
|
||||
if (pageBreak) {
|
||||
PushChildren(kidFrame, prevKidFrame);
|
||||
PushChildren(rowGroups, childX);
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
break;
|
||||
}
|
||||
@ -3209,7 +3221,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
if (nextRowGroupFrame) {
|
||||
PlaceChild(aReflowState, kidFrame, desiredSize);
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
PushChildren(nextRowGroupFrame, kidFrame);
|
||||
PushChildren(rowGroups, childX + 1);
|
||||
aLastChildReflowed = kidFrame;
|
||||
break;
|
||||
}
|
||||
@ -3218,7 +3230,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
else { // we are not on top, push this rowgroup onto the next page
|
||||
if (prevKidFrame) { // we had a rowgroup before so push this
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
PushChildren(kidFrame, prevKidFrame);
|
||||
PushChildren(rowGroups, childX);
|
||||
aLastChildReflowed = prevKidFrame;
|
||||
break;
|
||||
}
|
||||
@ -3256,12 +3268,17 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
// Add the continuing frame to the sibling list
|
||||
continuingFrame->SetNextSibling(kidFrame->GetNextSibling());
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
// Update rowGroups with the new rowgroup, just as it
|
||||
// would have been if we had called OrderRowGroups
|
||||
// again. Note that rowGroups doesn't get used again after
|
||||
// we PushChildren below, anyway.
|
||||
rowGroups.InsertElementAt(continuingFrame, childX + 1);
|
||||
}
|
||||
// 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);
|
||||
PushChildren(rowGroups, childX + 1);
|
||||
}
|
||||
if (repeatedFooter) {
|
||||
kidAvailSize.height = repeatedFooterHeight;
|
||||
|
@ -686,8 +686,12 @@ protected:
|
||||
|
||||
nsIFrame* GetFirstBodyRowGroupFrame();
|
||||
PRBool MoveOverflowToChildList(nsPresContext* aPresContext);
|
||||
void PushChildren(nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling);
|
||||
/**
|
||||
* Push all our child frames from the aFrames array, in order, starting from the
|
||||
* frame at aPushFrom to the end of the array. The frames are put on our overflow
|
||||
* list or moved directly to our next-in-flow if one exists.
|
||||
*/
|
||||
void PushChildren(const nsAutoVoidArray& aFrames, PRInt32 aPushFrom);
|
||||
|
||||
public:
|
||||
// put the children frames in the display order (e.g. thead before tbody before tfoot)
|
||||
|
Loading…
Reference in New Issue
Block a user