From 3a00ff8d0efd692ad2479d6429ecc13b2aeb0e13 Mon Sep 17 00:00:00 2001 From: "fantasai.cvs%inkedblade.net" Date: Tue, 2 Oct 2007 05:57:46 +0000 Subject: [PATCH] paginate absolutely-positioned elements, b=154892 r+sr=roc a=roc git-svn-id: svn://10.0.0.236/trunk@237057 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsCSSFrameConstructor.cpp | 60 +++-- mozilla/layout/base/nsFrameManager.cpp | 11 +- mozilla/layout/base/nsLayoutUtils.cpp | 4 +- .../generic/nsAbsoluteContainingBlock.cpp | 77 +++++- .../generic/nsAbsoluteContainingBlock.h | 4 +- mozilla/layout/generic/nsBlockFrame.cpp | 57 +++-- .../layout/generic/nsBlockReflowContext.cpp | 4 +- mozilla/layout/generic/nsBlockReflowContext.h | 3 +- mozilla/layout/generic/nsBlockReflowState.cpp | 4 +- mozilla/layout/generic/nsContainerFrame.cpp | 66 ++++- mozilla/layout/generic/nsContainerFrame.h | 32 ++- mozilla/layout/generic/nsFrame.cpp | 13 +- mozilla/layout/generic/nsHTMLReflowState.cpp | 4 + mozilla/layout/generic/nsInlineFrame.cpp | 2 +- mozilla/layout/generic/nsPageContentFrame.cpp | 3 +- .../layout/generic/nsSimplePageSequence.cpp | 2 +- mozilla/layout/generic/nsViewportFrame.cpp | 2 +- .../abspos-overflow-01-cols.ref.xhtml | 73 ++++++ .../pagination/abspos-overflow-01-cols.xhtml | 188 ++++++++++++++ .../pagination/abspos-overflow-01.ref.xhtml | 47 ++++ .../pagination/abspos-overflow-01.xhtml | 201 +++++++++++++++ mozilla/layout/reftests/pagination/blank.html | 1 + .../dynamic-abspos-overflow-01-cols.ref.xhtml | 79 ++++++ .../dynamic-abspos-overflow-01-cols.xhtml | 238 ++++++++++++++++++ .../layout/reftests/pagination/reftest.list | 7 + mozilla/layout/reftests/reftest.list | 1 + 26 files changed, 1097 insertions(+), 86 deletions(-) create mode 100644 mozilla/layout/reftests/pagination/abspos-overflow-01-cols.ref.xhtml create mode 100644 mozilla/layout/reftests/pagination/abspos-overflow-01-cols.xhtml create mode 100644 mozilla/layout/reftests/pagination/abspos-overflow-01.ref.xhtml create mode 100644 mozilla/layout/reftests/pagination/abspos-overflow-01.xhtml create mode 100644 mozilla/layout/reftests/pagination/blank.html create mode 100644 mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.ref.xhtml create mode 100644 mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.xhtml create mode 100644 mozilla/layout/reftests/pagination/reftest.list diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index b09e11bdccb..880184a97ad 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -1712,9 +1712,12 @@ static nsIAtom* GetChildListNameFor(nsIFrame* aChildFrame) { nsIAtom* listName; - + + if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + listName = nsGkAtoms::overflowContainersList; + } // See if the frame is moved out of the flow - if (aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + else if (aChildFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { // Look at the style information to tell const nsStyleDisplay* disp = aChildFrame->GetStyleDisplay(); @@ -8102,10 +8105,6 @@ FindPreviousAnonymousSibling(nsIPresShell* aPresShell, prevSibling = GetLastSpecialSibling(prevSibling); } - // The frame may have a continuation. If so, we want the - // last continuation as our previous sibling. - prevSibling = prevSibling->GetLastContinuation(); - // If the frame is out-of-flow, GPFF() will have returned the // out-of-flow frame; we want the placeholder. if (prevSibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { @@ -8115,6 +8114,14 @@ FindPreviousAnonymousSibling(nsIPresShell* aPresShell, prevSibling = placeholderFrame; } + // The frame may have a continuation. If so, we want the + // last non-overflow-container continuation as our previous sibling. + prevSibling = prevSibling->GetLastContinuation(); + while (prevSibling->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + prevSibling = prevSibling->GetPrevInFlow(); + NS_ASSERTION(prevSibling, "first-in-flow can't be overflow container"); + } + // Found a previous sibling, we're done! return prevSibling; } @@ -8287,18 +8294,6 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIContent* aContainer, prevSibling = GetLastSpecialSibling(prevSibling); } - // The frame may have a continuation. Get the last continuation - prevSibling = prevSibling->GetLastContinuation(); - - // XXXbz should the IsValidSibling check be after we get the - // placeholder for out-of-flows? - const nsStyleDisplay* display = prevSibling->GetStyleDisplay(); - - if (aChild && !IsValidSibling(aContainerFrame, prevSibling, - display->mDisplay, (nsIContent&)*aChild, - childDisplay)) - continue; - // If the frame is out-of-flow, GPFF() will have returned the // out-of-flow frame; we want the placeholder. if (prevSibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { @@ -8308,6 +8303,20 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIContent* aContainer, prevSibling = placeholderFrame; } + // The frame may have a continuation. if so get the last + // non-overflow-container continuation. + prevSibling = prevSibling->GetLastContinuation(); + while (prevSibling->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + prevSibling = prevSibling->GetPrevInFlow(); + NS_ASSERTION(prevSibling, "first-in-flow can't be overflow container"); + } + + const nsStyleDisplay* display = prevSibling->GetStyleDisplay(); + if (aChild && !IsValidSibling(aContainerFrame, prevSibling, + display->mDisplay, (nsIContent&)*aChild, + childDisplay)) + continue; + #ifdef DEBUG nsIFrame* containerFrame = nsnull; containerFrame = mPresShell->GetPrimaryFrameFor(aContainer); @@ -9609,7 +9618,8 @@ UpdateViewsForTree(nsIFrame* aFrame, nsIViewManager* aViewManager, do { nsIFrame* child = aFrame->GetFirstChild(childList); while (child) { - if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + || (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { // only do frames that are in flow if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder // get out of flow frame and start over there @@ -9781,8 +9791,11 @@ nsCSSFrameConstructor::StyleChangeReflow(nsIFrame* aFrame) if (IsFrameSpecial(aFrame)) aFrame = GetIBContainingBlockFor(aFrame); - mPresShell->FrameNeedsReflow(aFrame, nsIPresShell::eStyleChange, - NS_FRAME_IS_DIRTY); + do { + mPresShell->FrameNeedsReflow(aFrame, nsIPresShell::eStyleChange, + NS_FRAME_IS_DIRTY); + aFrame = aFrame->GetNextContinuation(); + } while (aFrame); return NS_OK; } @@ -10562,6 +10575,11 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext, newFrame->AddStateBits(NS_FRAME_GENERATED_CONTENT); } + // A continuation of an out-of-flow is also an out-of-flow + if (aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + newFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW); + } + if (nextInFlow) { nextInFlow->SetPrevInFlow(newFrame); newFrame->SetNextInFlow(nextInFlow); diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index 4f6a12affb9..d8921e6d853 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -848,7 +848,8 @@ VerifyStyleTree(nsPresContext* aPresContext, nsIFrame* aFrame, do { child = aFrame->GetFirstChild(childList); while (child) { - if (NS_FRAME_OUT_OF_FLOW != (child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + || (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { // only do frames that are in flow if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder: first recurse and verify the out of flow frame, @@ -944,7 +945,8 @@ nsFrameManager::ReParentStyleContext(nsIFrame* aFrame) child = aFrame->GetFirstChild(childList); while (child) { // only do frames that are in flow - if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + || (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { if (nsGkAtoms::placeholderFrame == child->GetType()) { // get out of flow frame and recurse there nsIFrame* outOfFlowFrame = @@ -1317,8 +1319,9 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, do { nsIFrame* child = aFrame->GetFirstChild(childList); while (child) { - if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { - // only do frames that are in flow + if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + || (child->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { + // only do frames that don't have placeholders if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder // get out of flow frame and recur there nsIFrame* outOfFlowFrame = diff --git a/mozilla/layout/base/nsLayoutUtils.cpp b/mozilla/layout/base/nsLayoutUtils.cpp index a46beff6927..172bc9fa8ec 100644 --- a/mozilla/layout/base/nsLayoutUtils.cpp +++ b/mozilla/layout/base/nsLayoutUtils.cpp @@ -1134,8 +1134,10 @@ nsIFrame* nsLayoutUtils::GetParentOrPlaceholderFor(nsFrameManager* aFrameManager, nsIFrame* aFrame) { - if (aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + if ((aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) + && !(aFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { return aFrameManager->GetPlaceholderFrameFor(aFrame); + } return aFrame->GetParent(); } diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp index 35b0a02564b..e1d5166984f 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp @@ -123,19 +123,23 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, nsIFrame* aOldFrame) { NS_ASSERTION(GetChildListName() == aListName, "unexpected child list"); + nsIFrame* nif = aOldFrame->GetNextInFlow(); + if (nif) { + static_cast(nif->GetParent()) + ->DeleteNextInFlowChild(aOldFrame->PresContext(), nif); + } PRBool result = mAbsoluteFrames.DestroyFrame(aOldFrame); NS_ASSERTION(result, "didn't find frame to delete"); - // Because positioned frames aren't part of a flow, there's no additional - // work to do, e.g. reflowing sibling frames. And because positioned frames - // have a view, we don't need to repaint + return result ? NS_OK : NS_ERROR_FAILURE; } nsresult -nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, - nsPresContext* aPresContext, +nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, + nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, + nsReflowStatus& aReflowStatus, nscoord aContainingBlockWidth, nscoord aContainingBlockHeight, PRBool aCBWidthChanged, @@ -145,23 +149,61 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, // Initialize OUT parameter if (aChildBounds) aChildBounds->SetRect(0, 0, 0, 0); + nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; PRBool reflowAll = aReflowState.ShouldReflowAllKids(); nsIFrame* kidFrame; + nsOverflowContinuationTracker tracker(aPresContext, aDelegatingFrame, PR_TRUE); for (kidFrame = mAbsoluteFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { if (reflowAll || NS_SUBTREE_DIRTY(kidFrame) || FrameDependsOnContainer(kidFrame, aCBWidthChanged, aCBHeightChanged)) { // Reflow the frame - nsReflowStatus kidStatus; - ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, aContainingBlockWidth, - aContainingBlockHeight, kidFrame, kidStatus, aChildBounds); - } else if (aChildBounds) { - aChildBounds->UnionRect(*aChildBounds, kidFrame->GetOverflowRect() + - kidFrame->GetPosition()); + nsReflowStatus kidStatus = NS_FRAME_COMPLETE; + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, + aContainingBlockWidth, aContainingBlockHeight, + kidFrame, kidStatus, aChildBounds); + nsIFrame* nextFrame = kidFrame->GetNextInFlow(); + if (!NS_FRAME_IS_FULLY_COMPLETE(kidStatus)) { + // Need a continuation + if (!nextFrame) { + nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext, + aDelegatingFrame, kidFrame, nextFrame); + NS_ENSURE_SUCCESS(rv, rv); + kidFrame->SetNextSibling(nextFrame->GetNextSibling()); + nextFrame->SetNextSibling(nsnull); + } + // Add it as an overflow container. + //XXXfr This is a hack to fix some of our printing dataloss. + // See bug 154892. Not sure how to do it "right" yet; probably want + // to keep continuations within an nsAbsoluteContainingBlock eventually. + tracker.Insert(nextFrame, kidStatus); + reflowStatus = NS_FRAME_MERGE_INCOMPLETE(reflowStatus, kidStatus); + } + else { + // Delete any continuations + if (nextFrame) { + tracker.Finish(kidFrame); + static_cast(nextFrame->GetParent()) + ->DeleteNextInFlowChild(aPresContext, nextFrame); + } + } + } + else { + tracker.Skip(kidFrame, reflowStatus); + if (aChildBounds) { + aChildBounds->UnionRect(*aChildBounds, kidFrame->GetOverflowRect() + + kidFrame->GetPosition()); + } } } + // Abspos frames can't cause their parent to be incomplete, + // only overflow incomplete. + if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) + NS_FRAME_SET_OVERFLOW_INCOMPLETE(reflowStatus); + + aReflowStatus = NS_FRAME_MERGE_INCOMPLETE(reflowStatus, aReflowStatus); return NS_OK; } @@ -371,6 +413,19 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat // Send the WillReflow() notification and position the frame aKidFrame->WillReflow(aPresContext); + PRBool constrainHeight = (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) + && (nsGkAtoms::fixedList != GetChildListName()) + // Don't split fixed frames + && (aDelegatingFrame->GetType() != nsGkAtoms::positionedInlineFrame) + //XXX we don't handle splitting frames for inline absolute containing blocks yet + && (aKidFrame->GetRect().y <= aReflowState.availableHeight); + // Don't split things below the fold. (Ideally we shouldn't *have* + // anything totally below the fold, but we can't position frames + // across next-in-flow breaks yet. + if (constrainHeight) { + kidReflowState.availableHeight = aReflowState.availableHeight - aKidFrame->GetRect().y; + } + // Do the reflow rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.h b/mozilla/layout/generic/nsAbsoluteContainingBlock.h index b64b8078f1e..4625ce53301 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.h +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.h @@ -46,6 +46,7 @@ #include "nsFrameList.h" #include "nsHTMLReflowState.h" #include "nsGkAtoms.h" +#include "nsContainerFrame.h" class nsIAtom; class nsIFrame; @@ -113,9 +114,10 @@ public: // positioned frames may be skipped based on whether they use // placeholders for positioning and on whether the containing block // width or height changed. - nsresult Reflow(nsIFrame* aDelegatingFrame, + nsresult Reflow(nsContainerFrame* aDelegatingFrame, nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, + nsReflowStatus& aReflowStatus, nscoord aContainingBlockWidth, nscoord aContainingBlockHeight, PRBool aCBWidthChanged, diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 1eaeeb2150e..22b6158b603 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -1134,6 +1134,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, aMetrics.height != oldSize.height; rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, + state.mReflowStatus, containingBlockSize.width, containingBlockSize.height, cbWidthChanged, cbHeightChanged, @@ -1278,7 +1279,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, // We may have stretched the frame beyond its computed height. Oh well. computedHeightLeftOver = PR_MAX(0, computedHeightLeftOver); } - NS_ASSERTION(!( (mState & NS_FRAME_IS_OVERFLOW_CONTAINER) + NS_ASSERTION(!( IS_TRUE_OVERFLOW_CONTAINER(this) && computedHeightLeftOver ), "overflow container must not have computedHeightLeftOver"); @@ -1362,6 +1363,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, aMetrics.height = autoHeight; } + if (IS_TRUE_OVERFLOW_CONTAINER(this) && + NS_FRAME_IS_NOT_COMPLETE(aState.mReflowStatus)) { + // Overflow containers can only be overflow complete. + // Note that auto height overflow containers have no normal children + NS_ASSERTION(aMetrics.height == 0, "overflow containers must be zero-height"); + NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + } + #ifdef DEBUG_blocks if (CRAZY_WIDTH(aMetrics.width) || CRAZY_HEIGHT(aMetrics.height)) { ListTag(stdout); @@ -1975,7 +1984,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState) // (First, see if there is such a line, and second, see if it's clean) if (!bifLineIter.Next() || !bifLineIter.GetLine()->IsDirty()) { - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + if (IS_TRUE_OVERFLOW_CONTAINER(aState.mNextInFlow)) + NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + else + NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); skipPull=PR_TRUE; } } @@ -2941,7 +2953,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, nsReflowStatus frameReflowStatus = NS_FRAME_COMPLETE; rv = brc.ReflowBlock(availSpace, applyTopMargin, aState.mPrevBottomMargin, clearance, aState.IsAdjacentWithTop(), computedOffsets, - aLine.get(), blockHtmlRS, frameReflowStatus); + aLine.get(), blockHtmlRS, frameReflowStatus, aState); // If this was a second-pass reflow and the block's vertical position // changed, invalidates from the first pass might have happened in the @@ -5044,25 +5056,24 @@ nsBlockFrame::RemoveFrame(nsIAtom* aListName, void nsBlockFrame::DoRemoveOutOfFlowFrame(nsIFrame* aFrame) { - // First remove aFrame's next in flow - nsIFrame* nextInFlow = aFrame->GetNextInFlow(); - if (nextInFlow) { - nsBlockFrame::DoRemoveOutOfFlowFrame(nextInFlow); - } - // Now remove aFrame - const nsStyleDisplay* display = aFrame->GetStyleDisplay(); - // The containing block is always the parent of aFrame. nsBlockFrame* block = (nsBlockFrame*)aFrame->GetParent(); // Remove aFrame from the appropriate list. + const nsStyleDisplay* display = aFrame->GetStyleDisplay(); if (display->IsAbsolutelyPositioned()) { + // This also deletes the next-in-flows block->mAbsoluteContainer.RemoveFrame(block, nsGkAtoms::absoluteList, aFrame); - aFrame->Destroy(); } else { + // First remove aFrame's next in flow + nsIFrame* nextInFlow = aFrame->GetNextInFlow(); + if (nextInFlow) { + nsBlockFrame::DoRemoveOutOfFlowFrame(nextInFlow); + } + // Now remove aFrame // This also destroys the frame. block->RemoveFloat(aFrame); } @@ -5184,21 +5195,23 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRBool aDestroyFrames, { // Clear our line cursor, since our lines may change. ClearLineCursor(); - + + nsPresContext* presContext = PresContext(); + if (NS_FRAME_IS_OVERFLOW_CONTAINER & aDeletedFrame->GetStateBits()) { + if (aDestroyFrames) + nsContainerFrame::DeleteNextInFlowChild(presContext, aDeletedFrame); + else + return nsContainerFrame::StealFrame(presContext, aDeletedFrame); + } + if (aDeletedFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { NS_ASSERTION(aDestroyFrames, "We can't not destroy out of flows"); DoRemoveOutOfFlowFrame(aDeletedFrame); return NS_OK; } - nsPresContext* presContext = PresContext(); nsIPresShell* presShell = presContext->PresShell(); - if (NS_FRAME_IS_OVERFLOW_CONTAINER & aDeletedFrame->GetStateBits()) { - nsContainerFrame::DeleteNextInFlowChild(presContext, aDeletedFrame); - return NS_OK; - } - PRBool isPlaceholder = nsGkAtoms::placeholderFrame == aDeletedFrame->GetType(); if (isPlaceholder) { nsFrameList* overflowPlaceholders = GetOverflowPlaceholders(); @@ -5593,7 +5606,7 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, rv = brc.ReflowBlock(availSpace, PR_TRUE, margin, 0, isAdjacentWithTop, offsets, nsnull, floatRS, - aReflowStatus); + aReflowStatus, aState); } while (NS_SUCCEEDED(rv) && clearanceFrame); // An incomplete reflow status means we should split the float @@ -5705,7 +5718,7 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, PRIntn nsBlockFrame::GetSkipSides() const { - if (mState & NS_FRAME_IS_OVERFLOW_CONTAINER) + if (IS_TRUE_OVERFLOW_CONTAINER(this)) return (1 << NS_SIDE_TOP) | (1 << NS_SIDE_BOTTOM); PRIntn skip = 0; @@ -5713,7 +5726,7 @@ nsBlockFrame::GetSkipSides() const skip |= 1 << NS_SIDE_TOP; } nsIFrame* nif = GetNextInFlow(); - if (nif && !(nif->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { + if (nif && !IS_TRUE_OVERFLOW_CONTAINER(nif)) { skip |= 1 << NS_SIDE_BOTTOM; } return skip; diff --git a/mozilla/layout/generic/nsBlockReflowContext.cpp b/mozilla/layout/generic/nsBlockReflowContext.cpp index 5ee0292ad02..2fbf0f2a601 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.cpp +++ b/mozilla/layout/generic/nsBlockReflowContext.cpp @@ -250,7 +250,8 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, nsMargin& aComputedOffsets, nsLineBox* aLine, nsHTMLReflowState& aFrameRS, - nsReflowStatus& aFrameReflowStatus) + nsReflowStatus& aFrameReflowStatus, + nsBlockReflowState& aState) { nsresult rv = NS_OK; mFrame = aFrameRS.frame; @@ -377,6 +378,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, // Floats will eventually be removed via nsBlockFrame::RemoveFloat // which detaches the placeholder from the float. /* XXX promote DeleteChildsNextInFlow to nsIFrame to elminate this cast */ + aState.mOverflowTracker.Finish(mFrame); static_cast(kidNextInFlow->GetParent()) ->DeleteNextInFlowChild(mPresContext, kidNextInFlow); } diff --git a/mozilla/layout/generic/nsBlockReflowContext.h b/mozilla/layout/generic/nsBlockReflowContext.h index d4a5c87923c..14bf3c750e5 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.h +++ b/mozilla/layout/generic/nsBlockReflowContext.h @@ -71,7 +71,8 @@ public: nsMargin& aComputedOffsets, nsLineBox* aLine, nsHTMLReflowState& aReflowState, - nsReflowStatus& aReflowStatus); + nsReflowStatus& aReflowStatus, + nsBlockReflowState& aState); PRBool PlaceBlock(const nsHTMLReflowState& aReflowState, PRBool aForceFit, diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 403f1b93fa7..e97452a47a4 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -72,11 +72,11 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState, mLineNumber(0), mFlags(0), mFloatBreakType(NS_STYLE_CLEAR_NONE), - mOverflowTracker(aPresContext, aFrame) + mOverflowTracker(aPresContext, aFrame, PR_FALSE) { SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nsnull); SetFlag(BRS_ISOVERFLOWCONTAINER, - !!(aFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)); + IS_TRUE_OVERFLOW_CONTAINER(aFrame)); const nsMargin& borderPadding = BorderPadding(); diff --git a/mozilla/layout/generic/nsContainerFrame.cpp b/mozilla/layout/generic/nsContainerFrame.cpp index 95b60b0c740..4c34e3e6f2c 100644 --- a/mozilla/layout/generic/nsContainerFrame.cpp +++ b/mozilla/layout/generic/nsContainerFrame.cpp @@ -717,12 +717,12 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, // If the reflow was successful and the child frame is complete, delete any // next-in-flows if (NS_SUCCEEDED(result) && NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { - if (aTracker) aTracker->Finish(aKidFrame); nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow(); if (nsnull != kidNextInFlow) { // Remove all of the childs next-in-flows. Make sure that we ask // the right parent to do the removal (it's possible that the // parent is not this because we are executing pullup code) + if (aTracker) aTracker->Finish(aKidFrame); static_cast(kidNextInFlow->GetParent()) ->DeleteNextInFlowChild(aPresContext, kidNextInFlow); } @@ -877,7 +877,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres if (!overflowContainers) return NS_OK; // nothing to reflow - nsOverflowContinuationTracker tracker(aPresContext, this, PR_FALSE); + nsOverflowContinuationTracker tracker(aPresContext, this, PR_FALSE, PR_FALSE); for (nsIFrame* frame = overflowContainers->FirstChild(); frame; frame = frame->GetNextSibling()) { if (NS_SUBTREE_DIRTY(frame)) { @@ -896,9 +896,13 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres frame, availSpace); nsReflowStatus frameStatus = NS_FRAME_COMPLETE; + // Cache old bounds + nsRect oldRect = frame->GetRect(); + nsRect oldOverflow = frame->GetOverflowRect(); + // Reflow rv = ReflowChild(frame, aPresContext, desiredSize, frameState, - prevRect.x, 0, aFlags, frameStatus); + prevRect.x, 0, aFlags, frameStatus, &tracker); NS_ENSURE_SUCCESS(rv, rv); //XXXfr Do we need to override any shrinkwrap effects here? // e.g. desiredSize.width = prevRect.width; @@ -906,10 +910,30 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres prevRect.x, 0, aFlags); NS_ENSURE_SUCCESS(rv, rv); + // Invalidate if there was a position or size change + nsRect rect = frame->GetRect(); + if (rect != oldRect) { + nsRect dirtyRect = oldOverflow; + dirtyRect.MoveBy(oldRect.x, oldRect.y); + Invalidate(dirtyRect); + + dirtyRect = frame->GetOverflowRect(); + dirtyRect.MoveBy(rect.x, rect.y); + Invalidate(dirtyRect); + } + // Handle continuations - NS_ASSERTION(NS_FRAME_IS_COMPLETE(frameStatus), - "overflow container frames can't be incomplete, only overflow-incomplete"); if (!NS_FRAME_IS_FULLY_COMPLETE(frameStatus)) { + if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + // Abspos frames can't cause their parent to be incomplete, + // only overflow incomplete. + NS_FRAME_SET_OVERFLOW_INCOMPLETE(frameStatus); + } + else { + NS_ASSERTION(NS_FRAME_IS_COMPLETE(frameStatus), + "overflow container frames can't be incomplete, only overflow-incomplete"); + } + // Acquire a next-in-flow, creating it if necessary nsIFrame* nif = frame->GetNextInFlow(); if (!nif) { @@ -1018,6 +1042,8 @@ nsContainerFrame::DeleteNextInFlowChild(nsPresContext* aPresContext, } } + aNextInFlow->Invalidate(aNextInFlow->GetOverflowRect()); + // Disconnect the next-in-flow from the flow list nsSplittableFrame::BreakFromPrevFlow(aNextInFlow); @@ -1228,12 +1254,14 @@ nsContainerFrame::MoveOverflowToChildList(nsPresContext* aPresContext) nsOverflowContinuationTracker::nsOverflowContinuationTracker(nsPresContext* aPresContext, nsContainerFrame* aFrame, + PRBool aWalkOOFFrames, PRBool aSkipOverflowContainerChildren) : mOverflowContList(nsnull), mPrevOverflowCont(nsnull), mSentry(nsnull), mParent(aFrame), - mSkipOverflowContainerChildren(aSkipOverflowContainerChildren) + mSkipOverflowContainerChildren(aSkipOverflowContainerChildren), + mWalkOOFFrames(aWalkOOFFrames) { NS_PRECONDITION(aFrame, "null frame pointer"); nsContainerFrame* next = static_cast @@ -1274,6 +1302,10 @@ nsOverflowContinuationTracker::SetUpListWalker() mPrevOverflowCont = cur; cur = cur->GetNextSibling(); } + while (cur && (mWalkOOFFrames == cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + mPrevOverflowCont = cur; + cur = cur->GetNextSibling(); + } } if (cur) { mSentry = cur->GetPrevInFlow(); @@ -1283,9 +1315,9 @@ nsOverflowContinuationTracker::SetUpListWalker() /** * Helper function to step forward through the overflow continuations list. - * Sets mSentry and mPrevOverflowCont as appropriate. - * May only be called when we have already set up an mOverflowContList; - * mOverflowContList cannot be null. + * Sets mSentry and mPrevOverflowCont, skipping over OOF or non-OOF frames + * as appropriate. May only be called when we have already set up an + * mOverflowContList; mOverflowContList cannot be null. */ void nsOverflowContinuationTracker::StepForward() @@ -1300,6 +1332,15 @@ nsOverflowContinuationTracker::StepForward() mPrevOverflowCont = mOverflowContList->FirstChild(); } + // Skip over oof or non-oof frames as appropriate + if (mSkipOverflowContainerChildren) { + nsIFrame* cur = mPrevOverflowCont->GetNextSibling(); + while (cur && (mWalkOOFFrames == cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + mPrevOverflowCont = cur; + cur = cur->GetNextSibling(); + } + } + // Set up the sentry mSentry = (mPrevOverflowCont->GetNextSibling()) ? mPrevOverflowCont->GetNextSibling()->GetPrevInFlow() @@ -1363,7 +1404,7 @@ nsOverflowContinuationTracker::Finish(nsIFrame* aChild) { NS_PRECONDITION(aChild, "null ptr"); NS_PRECONDITION(aChild->GetNextInFlow(), - "supposed to call Next *before* deleting next-in-flow!"); + "supposed to call Finish *before* deleting next-in-flow!"); if (aChild == mSentry) { // Make sure we drop all references if this was the only frame // in the overflow containers list @@ -1377,8 +1418,9 @@ nsOverflowContinuationTracker::Finish(nsIFrame* aChild) else { // Don't move the mPrevOverflowCont, but shift the sentry // The intervening overflow continuation will be deleted by our caller - nsIFrame* sentryCont = aChild->GetNextInFlow()->GetNextSibling(); - mSentry = (sentryCont) ? sentryCont->GetPrevInFlow() : nsnull; + nsIFrame* prevOverflowCont = mPrevOverflowCont; + StepForward(); + mPrevOverflowCont = prevOverflowCont; } } } diff --git a/mozilla/layout/generic/nsContainerFrame.h b/mozilla/layout/generic/nsContainerFrame.h index a9d040c5c67..0588235f799 100644 --- a/mozilla/layout/generic/nsContainerFrame.h +++ b/mozilla/layout/generic/nsContainerFrame.h @@ -413,6 +413,22 @@ protected: nsFrameList mFrames; }; +// ========================================================================== +/* The out-of-flow-related code below is for a hacky way of splitting + * absolutely-positioned frames. Basically what we do is split the frame + * in nsAbsoluteContainingBlock and pretend the continuation is an overflow + * container. This isn't an ideal solution, but it lets us print the content + * at least. See bug 154892. + */ + +#define IS_TRUE_OVERFLOW_CONTAINER(frame) \ + ( (frame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) \ + && !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) ) +//XXXfr This check isn't quite correct, because it doesn't handle cases +// where the out-of-flow has overflow.. but that's rare. +// We'll need to revisit the way abspos continuations are handled later +// for various reasons, this detail is one of them. See bug 154892 + /** * Helper class for tracking overflow container continuations during reflow. * @@ -442,12 +458,17 @@ public: * Initializes an nsOverflowContinuationTracker to help track overflow * continuations of aFrame's children. Typically invoked on 'this'. * + * aWalkOOFFrames determines whether the walker skips out-of-flow frames + * or skips non-out-of-flow frames. + * * Don't set aSkipOverflowContainerChildren to PR_FALSE unless you plan * to walk your own overflow container children. (Usually they are handled - * by calling ReflowOverflowContainerChildren.) + * by calling ReflowOverflowContainerChildren.) aWalkOOFFrames is ignored + * if aSkipOverflowContainerChildren is false. */ nsOverflowContinuationTracker(nsPresContext* aPresContext, nsContainerFrame* aFrame, + PRBool aWalkOOFFrames, PRBool aSkipOverflowContainerChildren = PR_TRUE); /** * This function adds an overflow continuation to our running list and @@ -471,8 +492,9 @@ public: nsresult Insert(nsIFrame* aOverflowCont, nsReflowStatus& aReflowStatus); /** - * This function should be called for each child that is reflowed - * but no longer has an overflow continuation. It increments our + * This function must be called for each child that is reflowed + * but no longer has an overflow continuation. (It may be called for + * other children, but in that case has no effect.) It increments our * walker and makes sure we drop any dangling pointers to its * next-in-flow. This function MUST be called before stealing or * deleting aChild's next-in-flow. @@ -524,8 +546,10 @@ private: overflowContainersProperty */ nsContainerFrame* mParent; /* Tells SetUpListWalker whether or not to walk us past any continuations - of overflow containers. */ + of overflow containers. aWalkOOFFrames is ignored when this is false. */ PRBool mSkipOverflowContainerChildren; + /* Tells us whether to pay attention to OOF frames or non-OOF frames */ + PRBool mWalkOOFFrames; }; #endif /* nsContainerFrame_h___ */ diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 539d8d741b0..f6c7cc607c9 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -4958,6 +4958,10 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, nsIFrame** aContainingBlock) if (thisBlock->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { //if we are searching for a frame that is not in flow we will not find it. //we must instead look for its placeholder + if (thisBlock->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + // abspos continuations don't have placeholders, get the fif + thisBlock = thisBlock->GetFirstInFlow(); + } thisBlock = frameManager->GetPlaceholderFrameFor(thisBlock); if (!thisBlock) return -1; @@ -5444,8 +5448,15 @@ nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, // For out-of-flow frames, we must resolve underneath the // placeholder's parent. + nsIFrame* oofFrame = this; + if ((oofFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) + && (oofFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { + // Out of flows that are overflow containers do not + // have placeholders. Use their first-in-flow's placeholder. + oofFrame = oofFrame->GetFirstInFlow(); + } nsIFrame *placeholder = - aPresContext->FrameManager()->GetPlaceholderFrameFor(this); + aPresContext->FrameManager()->GetPlaceholderFrameFor(oofFrame); if (!placeholder) { NS_NOTREACHED("no placeholder frame for out-of-flow frame"); GetCorrectedParent(aPresContext, this, aProviderFrame); diff --git a/mozilla/layout/generic/nsHTMLReflowState.cpp b/mozilla/layout/generic/nsHTMLReflowState.cpp index d97acf487de..dda95a43d03 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.cpp +++ b/mozilla/layout/generic/nsHTMLReflowState.cpp @@ -522,6 +522,10 @@ nsHTMLReflowState::InitFrameType() if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { if (disp->IsAbsolutelyPositioned()) { frameType = NS_CSS_FRAME_TYPE_ABSOLUTE; + //XXXfr hack for making frames behave properly when in overflow container lists + // see bug 154892; need to revisit later + if (frame->GetPrevInFlow()) + frameType = NS_CSS_FRAME_TYPE_BLOCK; } else if (NS_STYLE_FLOAT_NONE != disp->mFloats) { frameType = NS_CSS_FRAME_TYPE_FLOATING; diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index 16076084661..495cd403c7e 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -1131,7 +1131,7 @@ nsPositionedInlineFrame::Reflow(nsPresContext* aPresContext, // Don't include this frame's bounds, nor its inline descendants' bounds, // and don't store the overflow property. // That will all be done by nsLineLayout::RelativePositionFrames. - rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, + rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus, containingBlockWidth, containingBlockHeight, PR_TRUE, PR_TRUE, // XXX could be optimized &aDesiredSize.mOverflowArea); diff --git a/mozilla/layout/generic/nsPageContentFrame.cpp b/mozilla/layout/generic/nsPageContentFrame.cpp index 75a3803c2c7..0eae99025bb 100644 --- a/mozilla/layout/generic/nsPageContentFrame.cpp +++ b/mozilla/layout/generic/nsPageContentFrame.cpp @@ -115,7 +115,6 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, } if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) { nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); - NS_FRAME_SET_INCOMPLETE(aStatus); // page frames can't have overflow } } @@ -147,7 +146,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, !frame->GetNextInFlow(), "bad child flow list"); } // Reflow our fixed frames - mFixedContainer.Reflow(this, aPresContext, aReflowState, + mFixedContainer.Reflow(this, aPresContext, aReflowState, aStatus, aReflowState.availableWidth, aReflowState.availableHeight, PR_TRUE, PR_TRUE); // XXX could be optimized diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index d2ed8385cb8..57d90c89582 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -307,7 +307,7 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, // Is the page complete? nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow(); - if (NS_FRAME_IS_COMPLETE(status)) { + if (NS_FRAME_IS_FULLY_COMPLETE(status)) { NS_ASSERTION(nsnull == kidNextInFlow, "bad child flow list"); } else if (nsnull == kidNextInFlow) { // The page isn't complete and it doesn't have a next-in-flow, so diff --git a/mozilla/layout/generic/nsViewportFrame.cpp b/mozilla/layout/generic/nsViewportFrame.cpp index 27a4133ab83..d602397cbcb 100644 --- a/mozilla/layout/generic/nsViewportFrame.cpp +++ b/mozilla/layout/generic/nsViewportFrame.cpp @@ -316,7 +316,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext, #endif // Just reflow all the fixed-pos frames. - rv = mFixedContainer.Reflow(this, aPresContext, reflowState, + rv = mFixedContainer.Reflow(this, aPresContext, reflowState, aStatus, reflowState.ComputedWidth(), reflowState.ComputedHeight(), PR_TRUE, PR_TRUE); // XXX could be optimized diff --git a/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.ref.xhtml b/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.ref.xhtml new file mode 100644 index 00000000000..1bb252ec01b --- /dev/null +++ b/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.ref.xhtml @@ -0,0 +1,73 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced) + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ There must be a single green line and no red. +

+
+
+
+
+
+
+
+
+
+ + diff --git a/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.xhtml b/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.xhtml new file mode 100644 index 00000000000..1d9baf053de --- /dev/null +++ b/mozilla/layout/reftests/pagination/abspos-overflow-01-cols.xhtml @@ -0,0 +1,188 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced) + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ There must be a single green line and no red. +

+
+
+
+
+
+
+
+
+
+ + diff --git a/mozilla/layout/reftests/pagination/abspos-overflow-01.ref.xhtml b/mozilla/layout/reftests/pagination/abspos-overflow-01.ref.xhtml new file mode 100644 index 00000000000..cee3ca767f9 --- /dev/null +++ b/mozilla/layout/reftests/pagination/abspos-overflow-01.ref.xhtml @@ -0,0 +1,47 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced) + + + + + + +
+

+ There must be 3 pages, a single green line on each page, and no red. +

+

+

+
+ + diff --git a/mozilla/layout/reftests/pagination/abspos-overflow-01.xhtml b/mozilla/layout/reftests/pagination/abspos-overflow-01.xhtml new file mode 100644 index 00000000000..ba854ec76bf --- /dev/null +++ b/mozilla/layout/reftests/pagination/abspos-overflow-01.xhtml @@ -0,0 +1,201 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced) + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ There must be 3 pages, a single green line on each page, and no red. +

+
+
+
+
+
+
+
+
+ + diff --git a/mozilla/layout/reftests/pagination/blank.html b/mozilla/layout/reftests/pagination/blank.html new file mode 100644 index 00000000000..180da60ea81 --- /dev/null +++ b/mozilla/layout/reftests/pagination/blank.html @@ -0,0 +1 @@ + diff --git a/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.ref.xhtml b/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.ref.xhtml new file mode 100644 index 00000000000..4240ad17bb5 --- /dev/null +++ b/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.ref.xhtml @@ -0,0 +1,79 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced Dynamic Height) + + + + + + +

There must be a single green line with an orange square where + it intersects with the middle aqua line, and no red. The following + links must move the orange square to the intersection with the + indicated aqua line:

+

+ Left + Center + Right +

+
+
+
+
+
+
+
+ + diff --git a/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.xhtml b/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.xhtml new file mode 100644 index 00000000000..c84138093ce --- /dev/null +++ b/mozilla/layout/reftests/pagination/dynamic-abspos-overflow-01-cols.xhtml @@ -0,0 +1,238 @@ + + + + Multi-column Layout: AbsPos Pagination (Interlaced Dynamic Height) + + + + + + +

There must be a single green line with an orange square where + it intersects with the middle aqua line, and no red. The following + links must move the orange square to the intersection with the + indicated aqua line:

+

+ Left + Center + Right +

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+

+
+
+
+
+
+
+
+
+
+ + diff --git a/mozilla/layout/reftests/pagination/reftest.list b/mozilla/layout/reftests/pagination/reftest.list new file mode 100644 index 00000000000..b09baf2da98 --- /dev/null +++ b/mozilla/layout/reftests/pagination/reftest.list @@ -0,0 +1,7 @@ +# Sanity check +== blank.html blank.html + +# +== abspos-overflow-01.xhtml abspos-overflow-01.ref.xhtml +== abspos-overflow-01-cols.xhtml abspos-overflow-01-cols.ref.xhtml +# fails for no apparent reason on my system, uncomment if it passes on yours (my system is weird) == dynamic-abspos-overflow-01-cols.xhtml dynamic-abspos-overflow-01-cols.ref.xhtml diff --git a/mozilla/layout/reftests/reftest.list b/mozilla/layout/reftests/reftest.list index 31ca8782c6f..203adf50ac7 100644 --- a/mozilla/layout/reftests/reftest.list +++ b/mozilla/layout/reftests/reftest.list @@ -7,6 +7,7 @@ include reftest-sanity/reftest.list # printing include printing/reftest.list +include pagination/reftest.list # bugs/ include bugs/reftest.list