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);
// Fixed pos kids are taken care of directly in CreateContinuingFrame()
return NS_OK;
}
@ -10605,75 +10603,58 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
if (aFrame->GetStateBits() & 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
// the placeholders must be kids of a block, so we want to move over the
// 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) {
newFrame->Destroy();
*aContinuingFrame = nsnull;
return NS_OK;
}
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;
}
nsFrameItems fixedPlaceholders;
nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsGkAtoms::fixedList);
if (!firstFixed) {
return NS_OK;
}
//XXXbz Should mInitialContainingBlock be docRootFrame? It probably doesn't matter.
nsFrameConstructorState state(mPresShell, aParentFrame,
mInitialContainingBlock,
mInitialContainingBlock);
// Iterate the fixed frames and replicate each
for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
rv = ConstructFrame(state, fixed->GetContent(),
newFrame, fixedPlaceholders);
if (NS_FAILED(rv)) {
newFrame->Destroy();
*aContinuingFrame = nsnull;
return rv;
}
nsresult rv = ConstructFrame(state, fixed->GetContent(),
docRootFrame, fixedPlaceholders);
NS_ENSURE_SUCCESS(rv, rv);
}
// Add the placeholders to our primary child list.
// 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.
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;
}

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

@ -51,6 +51,7 @@
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsThreadUtils.h"
#include "nsPageContentFrame.h"
class nsIDocument;
struct nsFrameItems;
@ -185,6 +186,9 @@ public:
nsIFrame** aContinuingFrame,
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.
// This is typically called by the pres shell when there is no mapping in
// the pres shell hash table

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

@ -65,15 +65,24 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
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*>
(GetPrevInFlow());
if (prevPageContentFrame) {
(GetPrevInFlow());
if (mFrames.IsEmpty() && prevPageContentFrame) {
// Pull the doc root frame's continuation and copy fixed frames.
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
// children placeholders which don't get reflowed but must not be
// lost until the page content frame is destroyed.
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