Bug 389767 ��� Regression: Fixed-position items are missing on 2nd page of print-preview, fixed on behalf of HP, r+sr=bzbarsky

This commit is contained in:
fantasai.cvs%inkedblade.net 2007-08-07 16:06:57 +00:00
Родитель 8fb64ba2ea
Коммит 66cb01800e
3 изменённых файлов: 44 добавлений и 50 удалений

Просмотреть файл

@ -4649,8 +4649,6 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
aPageFrame->SetInitialChildList(nsnull, aPageContentFrame); aPageFrame->SetInitialChildList(nsnull, aPageContentFrame);
// Fixed pos kids are taken care of directly in CreateContinuingFrame()
return NS_OK; return NS_OK;
} }
@ -10605,75 +10603,58 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
if (aFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT) { if (aFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT) {
newFrame->AddStateBits(NS_FRAME_GENERATED_CONTENT); newFrame->AddStateBits(NS_FRAME_GENERATED_CONTENT);
} }
if (nextInFlow) {
nextInFlow->SetPrevInFlow(newFrame);
newFrame->SetNextInFlow(nextInFlow);
} else if (nextContinuation) {
nextContinuation->SetPrevContinuation(newFrame);
newFrame->SetNextContinuation(nextContinuation);
}
return NS_OK;
}
nsresult
nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
{
// Now deal with fixed-pos things.... They should appear on all pages, and // Now deal with fixed-pos things.... They should appear on all pages, and
// the placeholders must be kids of a block, so we want to move over the // the placeholders must be kids of a block, so we want to move over the
// placeholders when processing the child of the pageContentFrame. // placeholders when processing the child of the pageContentFrame.
if (!aParentFrame) {
return NS_OK;
}
if (aParentFrame->GetType() != nsGkAtoms::pageContentFrame) {
if (nextInFlow) {
nextInFlow->SetPrevInFlow(newFrame);
newFrame->SetNextInFlow(nextInFlow);
} else if (nextContinuation) {
nextContinuation->SetPrevContinuation(newFrame);
newFrame->SetNextContinuation(nextContinuation);
}
return NS_OK;
}
// Our parent is a page content frame. Look up its page frame and
// see whether it has a prev-in-flow.
nsIFrame* pageFrame = aParentFrame->GetParent();
if (!pageFrame) {
NS_ERROR("pageContentFrame does not have parent!");
newFrame->Destroy();
*aContinuingFrame = nsnull;
return NS_ERROR_UNEXPECTED;
}
nsIFrame* prevPage = pageFrame->GetPrevInFlow();
if (!prevPage) {
return NS_OK;
}
// OK. now we need to do this fixed-pos game.
// Get prevPage's page content frame
nsIFrame* prevPageContentFrame = prevPage->GetFirstChild(nsnull);
nsIFrame* prevPageContentFrame = aParentFrame->GetPrevInFlow();
if (!prevPageContentFrame) { if (!prevPageContentFrame) {
newFrame->Destroy(); return NS_OK;
*aContinuingFrame = nsnull; }
nsIFrame* docRootFrame = aParentFrame->GetFirstChild(nsnull);
if (!docRootFrame) {
// document's root element's frame: don't need a page if there's no content
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
nsFrameItems fixedPlaceholders; nsFrameItems fixedPlaceholders;
nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsGkAtoms::fixedList); nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsGkAtoms::fixedList);
if (!firstFixed) { if (!firstFixed) {
return NS_OK; return NS_OK;
} }
//XXXbz Should mInitialContainingBlock be docRootFrame? It probably doesn't matter.
nsFrameConstructorState state(mPresShell, aParentFrame, nsFrameConstructorState state(mPresShell, aParentFrame,
mInitialContainingBlock, mInitialContainingBlock,
mInitialContainingBlock); mInitialContainingBlock);
// Iterate the fixed frames and replicate each // Iterate the fixed frames and replicate each
for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) { for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
rv = ConstructFrame(state, fixed->GetContent(), nsresult rv = ConstructFrame(state, fixed->GetContent(),
newFrame, fixedPlaceholders); docRootFrame, fixedPlaceholders);
if (NS_FAILED(rv)) { NS_ENSURE_SUCCESS(rv, rv);
newFrame->Destroy();
*aContinuingFrame = nsnull;
return rv;
}
} }
// Add the placeholders to our primary child list. // Add the placeholders to our primary child list.
// XXXbz this is a little screwed up, since the fixed frames will have the // XXXbz this is a little screwed up, since the fixed frames will have the
// wrong parent block and hence auto-positioning will be broken. Oh, well. // wrong parent block and hence auto-positioning will be broken. Oh, well.
newFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList); NS_ASSERTION(!docRootFrame->GetFirstChild(nsnull),
"leaking frames; doc root continuation must be empty");
docRootFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsPageContentFrame.h"
class nsIDocument; class nsIDocument;
struct nsFrameItems; struct nsFrameItems;
@ -185,6 +186,9 @@ public:
nsIFrame** aContinuingFrame, nsIFrame** aContinuingFrame,
PRBool aIsFluid = PR_TRUE); PRBool aIsFluid = PR_TRUE);
// Copy over fixed frames from aParentFrame's prev-in-flow
nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
// Request to find the primary frame associated with a given content object. // Request to find the primary frame associated with a given content object.
// This is typically called by the pres shell when there is no mapping in // This is typically called by the pres shell when there is no mapping in
// the pres shell hash table // the pres shell hash table

Просмотреть файл

@ -65,15 +65,24 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
aStatus = NS_FRAME_COMPLETE; // initialize out parameter aStatus = NS_FRAME_COMPLETE; // initialize out parameter
// A PageContentFrame must always have one child: the doc root element's frame.
// We only need to get overflow frames if we don't already have that child;
// Also we need to avoid repeating the call to ReplicateFixedFrames.
nsPageContentFrame* prevPageContentFrame = static_cast<nsPageContentFrame*> nsPageContentFrame* prevPageContentFrame = static_cast<nsPageContentFrame*>
(GetPrevInFlow()); (GetPrevInFlow());
if (prevPageContentFrame) { if (mFrames.IsEmpty() && prevPageContentFrame) {
// Pull the doc root frame's continuation and copy fixed frames.
nsIFrame* overflow = prevPageContentFrame->GetOverflowFrames(aPresContext, PR_TRUE); nsIFrame* overflow = prevPageContentFrame->GetOverflowFrames(aPresContext, PR_TRUE);
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, overflow, prevPageContentFrame, this); NS_ASSERTION(overflow && !overflow->GetNextSibling(),
"must have doc root as pageContentFrame's only child");
nsHTMLContainerFrame::ReparentFrameView(aPresContext, overflow, prevPageContentFrame, this);
// Prepend overflow to the page content frame. There may already be // Prepend overflow to the page content frame. There may already be
// children placeholders which don't get reflowed but must not be // children placeholders which don't get reflowed but must not be
// lost until the page content frame is destroyed. // lost until the page content frame is destroyed.
mFrames.InsertFrames(this, nsnull, overflow); mFrames.InsertFrames(this, nsnull, overflow);
nsresult rv = aPresContext->PresShell()->FrameConstructor()
->ReplicateFixedFrames(this);
NS_ENSURE_SUCCESS(rv, rv);
} }
// Resize our frame allowing it only to be as big as we are // Resize our frame allowing it only to be as big as we are