fixed positioned elements print only on first and last pages b=417676 r+sr=roc

This commit is contained in:
fantasai.cvs@inkedblade.net 2008-02-24 04:19:17 -08:00
Родитель c436d8eac2
Коммит 23b243654b
8 изменённых файлов: 110 добавлений и 4 удалений

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

@ -387,8 +387,8 @@ protected:
* contains aPrevSibling and add aFrameList after aPrevSibling on that line.
* new lines are created as necessary to handle block data in aFrameList.
*/
nsresult AddFrames(nsIFrame* aFrameList,
nsIFrame* aPrevSibling);
virtual nsresult AddFrames(nsIFrame* aFrameList,
nsIFrame* aPrevSibling);
#ifdef IBMBIDI
/**

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

@ -1028,6 +1028,14 @@ nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder,
}
}
nsresult
nsContainerFrame::AddFrames(nsIFrame* aFrameList,
nsIFrame* aPrevSibling)
{
mFrames.InsertFrames(nsnull, aPrevSibling, aFrameList);
return NS_OK;
}
nsresult
nsContainerFrame::StealFrame(nsPresContext* aPresContext,
nsIFrame* aChild,

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

@ -272,6 +272,13 @@ public:
PRUint32 aFlags,
nsReflowStatus& aStatus);
/**
* Inserts aFrameList's frames into our main child list--without reparenting
* or requesting reflow.
*/
virtual nsresult AddFrames(nsIFrame* aFrameList,
nsIFrame* aPrevSibling);
/**
* Removes aChild without destroying it and without requesting reflow.
* Continuations are not affected. Checks the primary and overflow

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

@ -36,6 +36,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsPageContentFrame.h"
#include "nsPageFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsCSSFrameConstructor.h"
#include "nsHTMLContainerFrame.h"
#include "nsHTMLParts.h"
@ -68,6 +69,55 @@ nsPageContentFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
return nsSize(aAvailableWidth, height);
}
/**
* Returns true if aFrame is a placeholder for one of our fixed frames.
*/
inline PRBool
nsPageContentFrame::IsFixedPlaceholder(nsIFrame* aFrame)
{
if (!aFrame || nsGkAtoms::placeholderFrame != aFrame->GetType())
return PR_FALSE;
return static_cast<nsPlaceholderFrame*>(aFrame)->GetOutOfFlowFrame()
->GetParent() == this;
}
/**
* Steals replicated fixed placeholder frames from aDocRoot so they don't
* get in the way of reflow.
*/
inline nsFrameList
nsPageContentFrame::StealFixedPlaceholders(nsIFrame* aDocRoot)
{
nsPresContext* presContext = PresContext();
nsFrameList list;
if (GetPrevInFlow()) {
for (nsIFrame* f = aDocRoot->GetFirstChild(nsnull);
IsFixedPlaceholder(f); f = aDocRoot->GetFirstChild(nsnull)) {
nsresult rv = static_cast<nsContainerFrame*>(aDocRoot)
->StealFrame(presContext, f);
NS_ENSURE_SUCCESS(rv, list);
list.AppendFrame(nsnull, f);
}
}
return list;
}
/**
* Restores stolen replicated fixed placeholder frames to aDocRoot.
*/
static inline nsresult
ReplaceFixedPlaceholders(nsIFrame* aDocRoot,
nsFrameList& aPlaceholderList)
{
nsresult rv = NS_OK;
if (aPlaceholderList.NotEmpty()) {
rv = static_cast<nsContainerFrame*>(aDocRoot)
->AddFrames(aPlaceholderList.FirstChild(), nsnull);
}
return rv;
}
NS_IMETHODIMP
nsPageContentFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -77,6 +127,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
aStatus = NS_FRAME_COMPLETE; // initialize out parameter
nsresult rv = NS_OK;
// 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;
@ -107,8 +158,16 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
mPD->mPageContentSize = aReflowState.availableWidth;
// Reflow the page content area to get the child's desired size
ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
// Get replicated fixed frames' placeholders out of the way
nsFrameList stolenPlaceholders = StealFixedPlaceholders(frame);
// Reflow the page content area
rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
NS_ENSURE_SUCCESS(rv, rv);
// Put removed fixed placeholders back
rv = ReplaceFixedPlaceholders(frame, stolenPlaceholders);
NS_ENSURE_SUCCESS(rv, rv);
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
nsIFrame* nextFrame = frame->GetNextInFlow();

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

@ -87,6 +87,10 @@ protected:
nsPageContentFrame(nsStyleContext* aContext) : ViewportFrame(aContext) {}
nsSharedPageData* mPD;
private:
PRBool IsFixedPlaceholder(nsIFrame* aFrame);
nsFrameList StealFixedPlaceholders(nsIFrame* aDocRoot);
};
#endif /* nsPageContentFrame_h___ */

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

@ -0,0 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html class="reftest-print">
<title>Fixed Positioning Test</title>
<style type="text/css">
html, body { margin: 0; padding: 0; }
</style>
<div style="width: 3in; border: solid;">
This box must be repeated at this same position on the first, second, and third pages.
</div>
<div style="page-break-before: always; width: 3in; border: solid;">
This box must be repeated at this same position on the first, second, and third pages.
</div>
<div style="page-break-before: always; width: 3in; border: solid;">
This box must be repeated at this same position on the first, second, and third pages.
</div>

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

@ -0,0 +1,9 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html class="reftest-print">
<title>Fixed Positioning Test</title>
<div style="position: fixed; left: 0; top: 0; width: 3in; border: solid;">
This box must be repeated at this same position on the first, second, and third pages.
</div>
<p style="width: 0; height: 5in;">

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

@ -732,3 +732,4 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 414123.xhtml 414123-ref.xhtml
== 414851-1.html 414851-1-ref.html
== 416106-1.xhtml 416106-1-ref.xhtml
== 417676.html 417676-ref.html