mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 243519. Rework root element frame construction and the CanvasFrame so that the CanvasFrame is an abs-pos container and the root element frame can be positioned. r=fantasai,sr=dbaron
This commit is contained in:
parent
5afba26158
commit
311213e939
@ -3,6 +3,7 @@ load 143862-1.html
|
||||
load 143862-2.html
|
||||
load 243159-1.html
|
||||
load 243159-2.xhtml
|
||||
load 243519-1.html
|
||||
load 306940-1.html
|
||||
load 310267-1.xml
|
||||
load 310638-1.svg
|
||||
|
@ -1806,9 +1806,9 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
|
||||
, mUpdateCount(0)
|
||||
, mQuotesDirty(PR_FALSE)
|
||||
, mCountersDirty(PR_FALSE)
|
||||
, mInitialContainingBlockIsAbsPosContainer(PR_FALSE)
|
||||
, mIsDestroyingFrameTree(PR_FALSE)
|
||||
, mRebuildAllStyleData(PR_FALSE)
|
||||
, mHasRootAbsPosContainingBlock(PR_FALSE)
|
||||
{
|
||||
if (!gGotXBLFormPrefs) {
|
||||
gGotXBLFormPrefs = PR_TRUE;
|
||||
@ -3972,32 +3972,6 @@ nsCSSFrameConstructor::GetDisplay(nsIFrame* aFrame)
|
||||
* END TABLE SECTION
|
||||
***********************************************/
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructDocElementTableFrame(nsIContent* aDocElement,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame** aNewTableFrame,
|
||||
nsFrameConstructorState& aState)
|
||||
{
|
||||
nsFrameItems frameItems;
|
||||
|
||||
// XXXbz this is wrong. We should at least be setting the fixed container in
|
||||
// the framestate here. Better yet, we should pass through aState
|
||||
// unmodified. Can't do that, though, because then a fixed or absolute
|
||||
// positioned root table with auto offsets would look for a block to compute
|
||||
// its hypothetical box and crash. So we just disable fixed positioning
|
||||
// altogether in documents where the root is a table. Oh, well.
|
||||
nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull,
|
||||
aState.mFrameState);
|
||||
ConstructFrame(state, aDocElement, aParentFrame, frameItems);
|
||||
*aNewTableFrame = frameItems.childList;
|
||||
if (!*aNewTableFrame) {
|
||||
NS_WARNING("cannot get table contentFrame");
|
||||
// XXXbz maybe better to return the error from ConstructFrame?
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool CheckOverflow(nsPresContext* aPresContext,
|
||||
const nsStyleDisplay* aDisplay)
|
||||
{
|
||||
@ -4093,29 +4067,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
// how the root frame hierarchy should look
|
||||
|
||||
/*
|
||||
|
||||
---------------No Scrollbars------
|
||||
|
||||
|
||||
AreaFrame or BoxFrame (InitialContainingBlock)
|
||||
|
||||
|
||||
|
||||
---------------Gfx Scrollbars ------
|
||||
|
||||
|
||||
ScrollFrame
|
||||
|
||||
^
|
||||
|
|
||||
|
|
||||
AreaFrame or BoxFrame (InitialContainingBlock)
|
||||
|
||||
*/
|
||||
|
||||
*aNewFrame = nsnull;
|
||||
|
||||
if (!mTempFrameTreeState)
|
||||
@ -4189,8 +4140,13 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
"Scrollbars should have been propagated to the viewport");
|
||||
#endif
|
||||
|
||||
nsIFrame* contentFrame = nsnull;
|
||||
PRBool isBlockFrame = PR_FALSE;
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
if (mHasRootAbsPosContainingBlock) {
|
||||
// Push the absolute containing block now so we can absolutely position
|
||||
// the root element
|
||||
aState.PushAbsoluteContainingBlock(mDocElementContainingBlock, absoluteSaveState);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// The rules from CSS 2.1, section 9.2.4, have already been applied
|
||||
@ -4202,19 +4158,40 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
aDocElement->GetNameSpaceID(),
|
||||
styleContext);
|
||||
|
||||
// contentFrame is the primary frame for the root element. *aNewFrame
|
||||
// is the frame that will be the child of the initial containing block.
|
||||
// These are usually the same frame but they can be different, in
|
||||
// particular if the root frame is positioned, in which case
|
||||
// contentFrame is the out-of-flow frame and *aNewFrame is the
|
||||
// placeholder.
|
||||
nsIFrame* contentFrame;
|
||||
PRBool processChildren = PR_FALSE;
|
||||
if (docElemIsTable) {
|
||||
nsIFrame* innerTableFrame;
|
||||
nsFrameItems frameItems;
|
||||
// if the document is a table then just populate it.
|
||||
rv = ConstructDocElementTableFrame(aDocElement, aParentFrame, &contentFrame,
|
||||
aState);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = ConstructTableFrame(aState, aDocElement,
|
||||
aParentFrame, styleContext,
|
||||
kNameSpaceID_None, PR_FALSE, frameItems, contentFrame,
|
||||
innerTableFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
styleContext = contentFrame->GetStyleContext();
|
||||
if (!contentFrame || !frameItems.childList)
|
||||
return NS_ERROR_FAILURE;
|
||||
*aNewFrame = frameItems.childList;
|
||||
NS_ASSERTION(!frameItems.childList->GetNextSibling(),
|
||||
"multiple root element frames");
|
||||
} else {
|
||||
// otherwise build a box or a block
|
||||
#ifdef MOZ_XUL
|
||||
if (aDocElement->IsNodeOfType(nsINode::eXUL)) {
|
||||
contentFrame = NS_NewDocElementBoxFrame(mPresShell, styleContext);
|
||||
if (NS_UNLIKELY(!contentFrame)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
InitAndRestoreFrame(aState, aDocElement, aParentFrame, nsnull, contentFrame);
|
||||
*aNewFrame = contentFrame;
|
||||
processChildren = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -4222,6 +4199,26 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
if (aDocElement->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
if (aDocElement->Tag() == nsGkAtoms::svg && NS_SVGEnabled()) {
|
||||
contentFrame = NS_NewSVGOuterSVGFrame(mPresShell, aDocElement, styleContext);
|
||||
if (NS_UNLIKELY(!contentFrame)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
InitAndRestoreFrame(aState, aDocElement,
|
||||
aState.GetGeometricParent(display, aParentFrame),
|
||||
nsnull, contentFrame);
|
||||
|
||||
// AddChild takes care of transforming the frame tree for fixed-pos
|
||||
// or abs-pos situations
|
||||
nsFrameItems frameItems;
|
||||
rv = aState.AddChild(contentFrame, frameItems, aDocElement,
|
||||
styleContext, aParentFrame);
|
||||
if (NS_FAILED(rv) || !frameItems.childList) {
|
||||
return rv;
|
||||
}
|
||||
*aNewFrame = frameItems.childList;
|
||||
processChildren = PR_TRUE;
|
||||
|
||||
// See if we need to create a view, e.g. the frame is absolutely positioned
|
||||
nsHTMLContainerFrame::CreateViewForFrame(contentFrame, aParentFrame, PR_FALSE);
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -4229,25 +4226,27 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
else
|
||||
#endif
|
||||
{
|
||||
contentFrame = NS_NewDocumentElementFrame(mPresShell, styleContext);
|
||||
isBlockFrame = PR_TRUE;
|
||||
contentFrame = NS_NewBlockFrame(mPresShell, styleContext,
|
||||
NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
if (!contentFrame)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsFrameItems frameItems;
|
||||
rv = ConstructBlock(aState, display, aDocElement,
|
||||
aState.GetGeometricParent(display, aParentFrame),
|
||||
aParentFrame, styleContext, &contentFrame,
|
||||
frameItems, display->IsPositioned());
|
||||
if (NS_FAILED(rv) || !frameItems.childList)
|
||||
return rv;
|
||||
*aNewFrame = frameItems.childList;
|
||||
NS_ASSERTION(!frameItems.childList->GetNextSibling(),
|
||||
"multiple root element frames");
|
||||
}
|
||||
|
||||
if (NS_UNLIKELY(!contentFrame)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// initialize the child
|
||||
InitAndRestoreFrame(aState, aDocElement, aParentFrame, nsnull, contentFrame);
|
||||
}
|
||||
|
||||
// set the primary frame
|
||||
aState.mFrameManager->SetPrimaryFrameFor(aDocElement, contentFrame);
|
||||
|
||||
*aNewFrame = contentFrame;
|
||||
|
||||
mInitialContainingBlock = contentFrame;
|
||||
mInitialContainingBlockIsAbsPosContainer = PR_FALSE;
|
||||
|
||||
// Figure out which frame has the main style for the document element,
|
||||
// assigning it to mRootElementStyleFrame.
|
||||
@ -4259,31 +4258,19 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
||||
mRootElementStyleFrame = mInitialContainingBlock;
|
||||
}
|
||||
|
||||
// if it was a table then we don't need to process our children.
|
||||
if (!docElemIsTable) {
|
||||
// Process the child content
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
nsFrameConstructorSaveState floatSaveState;
|
||||
nsFrameItems childItems;
|
||||
|
||||
if (isBlockFrame) {
|
||||
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
||||
ShouldHaveSpecialBlockStyle(aDocElement, styleContext,
|
||||
&haveFirstLetterStyle, &haveFirstLineStyle);
|
||||
mInitialContainingBlockIsAbsPosContainer = PR_TRUE;
|
||||
aState.PushAbsoluteContainingBlock(contentFrame, absoluteSaveState);
|
||||
aState.PushFloatContainingBlock(contentFrame, floatSaveState,
|
||||
haveFirstLetterStyle,
|
||||
haveFirstLineStyle);
|
||||
}
|
||||
if (processChildren) {
|
||||
// Still need to process the child content
|
||||
nsFrameItems childItems;
|
||||
|
||||
// Create any anonymous frames the doc element frame requires
|
||||
// This must happen before ProcessChildren to ensure that popups are
|
||||
// never constructed before the popupset.
|
||||
CreateAnonymousFrames(nsnull, aState, aDocElement, contentFrame,
|
||||
PR_FALSE, childItems, PR_TRUE);
|
||||
NS_ASSERTION(!nsLayoutUtils::GetAsBlock(contentFrame),
|
||||
"Only XUL and SVG frames should reach here");
|
||||
ProcessChildren(aState, aDocElement, contentFrame, PR_TRUE, childItems,
|
||||
isBlockFrame);
|
||||
PR_FALSE);
|
||||
|
||||
// Set the initial child lists
|
||||
contentFrame->SetInitialChildList(nsnull, childItems.childList);
|
||||
@ -4300,36 +4287,62 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
|
||||
NS_PRECONDITION(aNewFrame, "null out param");
|
||||
|
||||
// how the root frame hierarchy should look
|
||||
|
||||
/*
|
||||
how the root frame hierarchy should look
|
||||
|
||||
---------------No Scrollbars------
|
||||
|
||||
|
||||
|
||||
ViewPortFrame (FixedContainingBlock) <---- RootView
|
||||
|
||||
^
|
||||
|
|
||||
RootFrame(DocElementContainingBlock)
|
||||
Galley presentation, non-XUL, with scrolling (i.e. not a frameset):
|
||||
|
||||
ViewportFrame [fixed-cb]
|
||||
nsHTMLScrollFrame
|
||||
CanvasFrame [abs-cb]
|
||||
root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
|
||||
nsTableOuterFrame, nsPlaceholderFrame)
|
||||
|
||||
Galley presentation, non-XUL, without scrolling (i.e. a frameset):
|
||||
|
||||
ViewportFrame [fixed-cb]
|
||||
CanvasFrame [abs-cb]
|
||||
root element frame (nsBlockFrame)
|
||||
|
||||
---------------Gfx Scrollbars ------
|
||||
Galley presentation, XUL
|
||||
|
||||
ViewportFrame [fixed-cb]
|
||||
nsRootBoxFrame
|
||||
root element frame (nsDocElementBoxFrame)
|
||||
|
||||
Print presentation, non-XUL
|
||||
|
||||
ViewPortFrame (FixedContainingBlock) <---- RootView
|
||||
ViewportFrame
|
||||
nsSimplePageSequenceFrame
|
||||
nsPageFrame [fixed-cb]
|
||||
nsPageContentFrame
|
||||
CanvasFrame [abs-cb]
|
||||
root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
|
||||
nsTableOuterFrame, nsPlaceholderFrame)
|
||||
|
||||
^
|
||||
|
|
||||
ScrollFrame
|
||||
Print-preview presentation, non-XUL
|
||||
|
||||
^
|
||||
|
|
||||
RootFrame(DocElementContainingBlock)
|
||||
|
||||
*/
|
||||
ViewportFrame
|
||||
nsHTMLScrollFrame
|
||||
nsSimplePageSequenceFrame
|
||||
nsPageFrame [fixed-cb]
|
||||
nsPageContentFrame
|
||||
CanvasFrame [abs-cb]
|
||||
root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
|
||||
nsTableOuterFrame, nsPlaceholderFrame)
|
||||
|
||||
Print/print preview of XUL is not supported.
|
||||
[fixed-cb]: the default containing block for fixed-pos content
|
||||
[abs-cb]: the default containing block for abs-pos content
|
||||
|
||||
Meaning of nsCSSFrameConstructor fields:
|
||||
mInitialContainingBlock is "root element frame".
|
||||
mDocElementContainingBlock is the parent of mInitialContainingBlock
|
||||
(i.e. CanvasFrame or nsRootBoxFrame)
|
||||
mFixedContainingBlock is the [fixed-cb]
|
||||
mGfxScrollFrame is the nsHTMLScrollFrame mentioned above, or null if there isn't one
|
||||
mPageSequenceFrame is the nsSimplePageSequenceFrame, or null if there isn't one
|
||||
*/
|
||||
|
||||
// Set up our style rule observer.
|
||||
{
|
||||
@ -4394,6 +4407,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
||||
{
|
||||
// pass a temporary stylecontext, the correct one will be set later
|
||||
rootFrame = NS_NewCanvasFrame(mPresShell, viewportPseudoStyle);
|
||||
mHasRootAbsPosContainingBlock = PR_TRUE;
|
||||
}
|
||||
|
||||
rootPseudo = nsCSSAnonBoxes::canvas;
|
||||
@ -4522,14 +4536,15 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
||||
if (isPaginated) { // paginated
|
||||
// Create the first page
|
||||
// Set the initial child lists
|
||||
nsIFrame *pageFrame, *pageContentFrame;
|
||||
nsIFrame *pageFrame, *canvasFrame;
|
||||
ConstructPageFrame(mPresShell, presContext, rootFrame, nsnull,
|
||||
pageFrame, pageContentFrame);
|
||||
pageFrame, canvasFrame);
|
||||
rootFrame->SetInitialChildList(nsnull, pageFrame);
|
||||
|
||||
// The eventual parent of the document element frame.
|
||||
// XXX should this be set for every new page (in ConstructPageFrame)?
|
||||
mDocElementContainingBlock = pageContentFrame;
|
||||
mDocElementContainingBlock = canvasFrame;
|
||||
mHasRootAbsPosContainingBlock = PR_TRUE;
|
||||
}
|
||||
|
||||
viewportFrame->SetInitialChildList(nsnull, newFrame);
|
||||
@ -4540,12 +4555,12 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aPrevPageFrame,
|
||||
nsIFrame*& aPageFrame,
|
||||
nsIFrame*& aPageContentFrame)
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aPrevPageFrame,
|
||||
nsIFrame*& aPageFrame,
|
||||
nsIFrame*& aCanvasFrame)
|
||||
{
|
||||
nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
|
||||
nsStyleSet *styleSet = aPresShell->StyleSet();
|
||||
@ -4568,8 +4583,8 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsCSSAnonBoxes::pageContent,
|
||||
pagePseudoStyle);
|
||||
|
||||
aPageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
|
||||
if (NS_UNLIKELY(!aPageContentFrame))
|
||||
nsIFrame* pageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
|
||||
if (NS_UNLIKELY(!pageContentFrame))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Initialize the page content frame and force it to have a view. Also make it the
|
||||
@ -4579,10 +4594,26 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
prevPageContentFrame = aPrevPageFrame->GetFirstChild(nsnull);
|
||||
NS_ASSERTION(prevPageContentFrame, "missing page content frame");
|
||||
}
|
||||
aPageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
|
||||
mFixedContainingBlock = aPageContentFrame;
|
||||
pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
|
||||
aPageFrame->SetInitialChildList(nsnull, pageContentFrame);
|
||||
mFixedContainingBlock = pageContentFrame;
|
||||
|
||||
aPageFrame->SetInitialChildList(nsnull, aPageContentFrame);
|
||||
nsRefPtr<nsStyleContext> canvasPseudoStyle;
|
||||
canvasPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
|
||||
nsCSSAnonBoxes::canvas,
|
||||
pageContentPseudoStyle);
|
||||
|
||||
aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
|
||||
if (NS_UNLIKELY(!aCanvasFrame))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsIFrame* prevCanvasFrame = nsnull;
|
||||
if (prevPageContentFrame) {
|
||||
prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
|
||||
NS_ASSERTION(prevCanvasFrame, "missing canvas frame");
|
||||
}
|
||||
aCanvasFrame->Init(nsnull, pageContentFrame, prevCanvasFrame);
|
||||
pageContentFrame->SetInitialChildList(nsnull, aCanvasFrame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -6681,17 +6712,24 @@ already_AddRefed<nsStyleContext>
|
||||
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
nsStyleContext* parentStyleContext;
|
||||
nsStyleContext* parentStyleContext = nsnull;
|
||||
if (aContent->GetParent()) {
|
||||
aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nsnull);
|
||||
|
||||
// Resolve the style context based on the content object and the parent
|
||||
// style context
|
||||
parentStyleContext = aParentFrame->GetStyleContext();
|
||||
if (aParentFrame) {
|
||||
// Resolve the style context based on the content object and the parent
|
||||
// style context
|
||||
parentStyleContext = aParentFrame->GetStyleContext();
|
||||
} else {
|
||||
// Perhaps aParentFrame is a canvasFrame and we're replicating
|
||||
// fixed-pos frames.
|
||||
// XXX should we create a way to tell ConstructFrame which style
|
||||
// context to use, and pass it the style context for the
|
||||
// previous page's fixed-pos frame?
|
||||
}
|
||||
} else {
|
||||
// This has got to be a call from ConstructDocElementTableFrame.
|
||||
// Not sure how best to asserrt that here.
|
||||
parentStyleContext = nsnull;
|
||||
// Not sure how best to assert that here.
|
||||
}
|
||||
|
||||
nsStyleSet *styleSet = mPresShell->StyleSet();
|
||||
@ -7507,23 +7545,40 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchyInternal()
|
||||
nsIContent *rootContent = mDocument->GetRootContent();
|
||||
|
||||
if (rootContent) {
|
||||
// Before removing the frames associated with the content object, ask them to save their
|
||||
// state onto a temporary state object.
|
||||
CaptureStateForFramesOf(rootContent, mTempFrameTreeState);
|
||||
|
||||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
nsnull, nsnull, mTempFrameTreeState);
|
||||
|
||||
// Before removing the frames associated with the content object, ask them to save their
|
||||
// state onto a temporary state object.
|
||||
CaptureStateFor(state.mFrameManager->GetRootFrame(), mTempFrameTreeState);
|
||||
|
||||
// Get the frame that corresponds to the document element
|
||||
nsIFrame* docElementFrame =
|
||||
state.mFrameManager->GetPrimaryFrameFor(rootContent, -1);
|
||||
|
||||
|
||||
if (docElementFrame) {
|
||||
// Destroy out-of-flow frames that might not be in the frame subtree
|
||||
// rooted at docElementFrame
|
||||
::DeletingFrameSubtree(state.mFrameManager, docElementFrame);
|
||||
}
|
||||
|
||||
// Remove any existing fixed items: they are always on the
|
||||
// FixedContainingBlock. Note that this has to be done before we call
|
||||
// ClearPlaceholderFrameMap(), since RemoveFixedItems uses the
|
||||
// placeholder frame map.
|
||||
rv = RemoveFixedItems(state);
|
||||
rv = RemoveFixedItems(state, docElementFrame);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsPlaceholderFrame* placeholderFrame = nsnull;
|
||||
if (docElementFrame &&
|
||||
(docElementFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// Get the placeholder frame now, before we tear down the
|
||||
// placeholder frame map
|
||||
placeholderFrame =
|
||||
state.mFrameManager->GetPlaceholderFrameFor(docElementFrame);
|
||||
NS_ASSERTION(placeholderFrame, "No placeholder for out-of-flow?");
|
||||
}
|
||||
|
||||
// Clear the hash tables that map from content to frame and out-of-flow
|
||||
// frame to placeholder frame
|
||||
state.mFrameManager->ClearPrimaryFrameMap();
|
||||
@ -7532,20 +7587,24 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchyInternal()
|
||||
|
||||
if (docElementFrame) {
|
||||
// Take the docElementFrame, and remove it from its parent.
|
||||
|
||||
// XXXbz So why can't we reuse ContentRemoved?
|
||||
|
||||
NS_ASSERTION(docElementFrame->GetParent() == mDocElementContainingBlock,
|
||||
"Unexpected doc element parent frame");
|
||||
|
||||
// Notify self that we will destroy the entire frame tree, this blocks
|
||||
// RemoveMappingsForFrameSubtree() which would otherwise lead to a
|
||||
// crash since we cleared the placeholder map above (bug 398982).
|
||||
PRBool wasDestroyingFrameTree = mIsDestroyingFrameTree;
|
||||
WillDestroyFrameTree();
|
||||
// Remove the old document element hieararchy
|
||||
rv = state.mFrameManager->RemoveFrame(mDocElementContainingBlock,
|
||||
nsnull, docElementFrame);
|
||||
|
||||
rv = state.mFrameManager->RemoveFrame(docElementFrame->GetParent(),
|
||||
GetChildListNameFor(docElementFrame), docElementFrame);
|
||||
|
||||
if (placeholderFrame) {
|
||||
// Remove the placeholder frame first (XXX second for now) (so
|
||||
// that it doesn't retain a dangling pointer to memory)
|
||||
rv |= state.mFrameManager->RemoveFrame(placeholderFrame->GetParent(),
|
||||
nsnull, placeholderFrame);
|
||||
}
|
||||
|
||||
mIsDestroyingFrameTree = wasDestroyingFrameTree;
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
@ -7642,9 +7701,8 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
|
||||
if (containingBlock)
|
||||
return AdjustAbsoluteContainingBlock(containingBlock);
|
||||
|
||||
// If we didn't find it, then use the initial containing block if it
|
||||
// supports abs pos kids.
|
||||
return mInitialContainingBlockIsAbsPosContainer ? mInitialContainingBlock : nsnull;
|
||||
// If we didn't find it, then use the document element containing block
|
||||
return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nsnull;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
@ -10229,9 +10287,9 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
} else if (nsGkAtoms::pageFrame == frameType) {
|
||||
nsIFrame* pageContentFrame;
|
||||
nsIFrame* canvasFrame;
|
||||
rv = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
|
||||
newFrame, pageContentFrame);
|
||||
newFrame, canvasFrame);
|
||||
} else if (nsGkAtoms::tableOuterFrame == frameType) {
|
||||
rv = CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
|
||||
content, styleContext, &newFrame);
|
||||
@ -10420,17 +10478,17 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
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.
|
||||
// Now deal with fixed-pos things.... They should appear on all pages,
|
||||
// so we want to move over the placeholders when processing the child
|
||||
// of the pageContentFrame.
|
||||
|
||||
nsIFrame* prevPageContentFrame = aParentFrame->GetPrevInFlow();
|
||||
if (!prevPageContentFrame) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIFrame* docRootFrame = aParentFrame->GetFirstChild(nsnull);
|
||||
nsIFrame* prevDocRootFrame = prevPageContentFrame->GetFirstChild(nsnull);
|
||||
if (!docRootFrame || !prevDocRootFrame) {
|
||||
nsIFrame* canvasFrame = aParentFrame->GetFirstChild(nsnull);
|
||||
nsIFrame* prevCanvasFrame = prevPageContentFrame->GetFirstChild(nsnull);
|
||||
if (!canvasFrame || !prevCanvasFrame) {
|
||||
// document's root element frame missing
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -10458,19 +10516,19 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
|
||||
nsIFrame* prevPlaceholder = nsnull;
|
||||
mPresShell->GetPlaceholderFrameFor(fixed, &prevPlaceholder);
|
||||
if (prevPlaceholder &&
|
||||
nsLayoutUtils::IsProperAncestorFrame(prevDocRootFrame, prevPlaceholder)) {
|
||||
nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
|
||||
nsresult rv = ConstructFrame(state, fixed->GetContent(),
|
||||
docRootFrame, fixedPlaceholders);
|
||||
canvasFrame, 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.
|
||||
NS_ASSERTION(!docRootFrame->GetFirstChild(nsnull),
|
||||
// XXXbz this is a little screwed up, since the fixed frames will have
|
||||
// broken auto-positioning. Oh, well.
|
||||
NS_ASSERTION(!canvasFrame->GetFirstChild(nsnull),
|
||||
"leaking frames; doc root continuation must be empty");
|
||||
docRootFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
|
||||
canvasFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -12801,7 +12859,9 @@ nsCSSFrameConstructor::ReframeContainingBlock(nsIFrame* aFrame)
|
||||
return ReconstructDocElementHierarchyInternal();
|
||||
}
|
||||
|
||||
nsresult nsCSSFrameConstructor::RemoveFixedItems(const nsFrameConstructorState& aState)
|
||||
nsresult
|
||||
nsCSSFrameConstructor::RemoveFixedItems(const nsFrameConstructorState& aState,
|
||||
nsIFrame *aRootElementFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
@ -12809,6 +12869,12 @@ nsresult nsCSSFrameConstructor::RemoveFixedItems(const nsFrameConstructorState&
|
||||
nsIFrame *fixedChild = nsnull;
|
||||
do {
|
||||
fixedChild = mFixedContainingBlock->GetFirstChild(nsGkAtoms::fixedList);
|
||||
if (fixedChild && fixedChild == aRootElementFrame) {
|
||||
// Skip the root element frame, if it happens to be fixed-positioned
|
||||
// It will be explicitly removed later in
|
||||
// ReconstructDocElementHierarchyInternal
|
||||
fixedChild = fixedChild->GetNextSibling();
|
||||
}
|
||||
if (fixedChild) {
|
||||
// Remove the placeholder so it doesn't end up sitting about pointing
|
||||
// to the removed fixed frame.
|
||||
|
@ -270,7 +270,7 @@ private:
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aPrevPageFrame,
|
||||
nsIFrame*& aPageFrame,
|
||||
nsIFrame*& aPageContentFrame);
|
||||
nsIFrame*& aCanvasFrame);
|
||||
|
||||
void DoContentStateChanged(nsIContent* aContent,
|
||||
PRInt32 aStateMask);
|
||||
@ -1049,7 +1049,8 @@ private:
|
||||
nsIFrame* aPrevSibling,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult RemoveFixedItems(const nsFrameConstructorState& aState);
|
||||
nsresult RemoveFixedItems(const nsFrameConstructorState& aState,
|
||||
nsIFrame* aRootElementFrame);
|
||||
|
||||
// Find the right frame to use for aContent when looking for sibling
|
||||
// frames for aTargetContent. If aPrevSibling is true, this
|
||||
@ -1164,6 +1165,9 @@ private:
|
||||
nsIDocument* mDocument; // Weak ref
|
||||
nsIPresShell* mPresShell; // Weak ref
|
||||
|
||||
// See the comment at the start of ConstructRootFrame for more details
|
||||
// about the following frames.
|
||||
|
||||
// This is not the real CSS 2.1 "initial containing block"! It is just
|
||||
// the outermost frame for the root element.
|
||||
nsIFrame* mInitialContainingBlock;
|
||||
@ -1181,9 +1185,10 @@ private:
|
||||
PRUint16 mUpdateCount;
|
||||
PRPackedBool mQuotesDirty : 1;
|
||||
PRPackedBool mCountersDirty : 1;
|
||||
PRPackedBool mInitialContainingBlockIsAbsPosContainer : 1;
|
||||
PRPackedBool mIsDestroyingFrameTree : 1;
|
||||
PRPackedBool mRebuildAllStyleData : 1;
|
||||
// This is true if mDocElementContainingBlock supports absolute positioning
|
||||
PRPackedBool mHasRootAbsPosContainingBlock : 1;
|
||||
|
||||
nsRevocableEventPtr<RestyleEvent> mRestyleEvent;
|
||||
|
||||
|
@ -52,17 +52,6 @@
|
||||
#include "nsBlockFrame.h"
|
||||
#endif
|
||||
|
||||
|
||||
nsresult
|
||||
nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame** aFirstChild) const
|
||||
{
|
||||
NS_PRECONDITION(GetChildListName() == aListName, "unexpected child list name");
|
||||
*aFirstChild = mAbsoluteFrames.FirstChild();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame* aDelegatingFrame,
|
||||
nsIAtom* aListName,
|
||||
|
@ -84,10 +84,7 @@ public:
|
||||
nsIAtom* GetChildListName() const { return mChildListName; }
|
||||
#endif
|
||||
|
||||
nsresult FirstChild(const nsIFrame* aDelegatingFrame,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame** aFirstChild) const;
|
||||
nsIFrame* GetFirstChild() { return mAbsoluteFrames.FirstChild(); }
|
||||
nsIFrame* GetFirstChild() const { return mAbsoluteFrames.FirstChild(); }
|
||||
|
||||
nsresult SetInitialChildList(nsIFrame* aDelegatingFrame,
|
||||
nsIAtom* aListName,
|
||||
|
@ -520,9 +520,7 @@ nsIFrame*
|
||||
nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
|
||||
{
|
||||
if (nsGkAtoms::absoluteList == aListName) {
|
||||
nsIFrame* result = nsnull;
|
||||
mAbsoluteContainer.FirstChild(this, aListName, &result);
|
||||
return result;
|
||||
return mAbsoluteContainer.GetFirstChild();
|
||||
}
|
||||
else if (nsnull == aListName) {
|
||||
return (mLines.empty()) ? nsnull : mLines.front()->mFirstChild;
|
||||
@ -803,9 +801,11 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
||||
cbSize.width -= border.LeftRight();
|
||||
cbSize.height -= border.TopBottom();
|
||||
|
||||
if (frame->GetParent()->GetContent() == frame->GetContent()) {
|
||||
// We are a wrapped frame for the content. Use the container's
|
||||
// dimensions, if they have been precomputed.
|
||||
if (frame->GetParent()->GetContent() == frame->GetContent() &&
|
||||
frame->GetParent()->GetType() != nsGkAtoms::canvasFrame) {
|
||||
// We are a wrapped frame for the content (and the wrapper is not the
|
||||
// canvas frame, whose size is not meaningful here).
|
||||
// Use the container's dimensions, if they have been precomputed.
|
||||
// XXX This is a hack! We really should be waiting until the outermost
|
||||
// frame is fully reflowed and using the resulting dimensions, even
|
||||
// if they're intrinsic.
|
||||
@ -816,14 +816,10 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
||||
// content.
|
||||
const nsHTMLReflowState* aLastRS = &aReflowState;
|
||||
const nsHTMLReflowState* lastButOneRS = &aReflowState;
|
||||
PRBool isCanvasBlock = PR_FALSE;
|
||||
while (aLastRS->parentReflowState &&
|
||||
aLastRS->parentReflowState->frame->GetContent() == frame->GetContent()) {
|
||||
lastButOneRS = aLastRS;
|
||||
aLastRS = aLastRS->parentReflowState;
|
||||
if (aLastRS->frame->GetType() == nsGkAtoms::canvasFrame) {
|
||||
isCanvasBlock = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (aLastRS != &aReflowState) {
|
||||
// Scrollbars need to be specifically excluded, if present, because they are outside the
|
||||
@ -844,23 +840,11 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
||||
}
|
||||
// We found a reflow state for the outermost wrapping frame, so use
|
||||
// its computed metrics if available
|
||||
// XXX grotesque hack for Firefox 2 compatibility until we can
|
||||
// properly fix abs-pos containers! If this is the block for
|
||||
// the root element, don't adjust the width here, just use the block's
|
||||
// width. We have to do this because the abs-pos frame will be
|
||||
// positioned relative to the block, not the canvas frame, and the
|
||||
// block might have borders and margin which will throw things off
|
||||
// if we use the canvas frame width.
|
||||
// Positioning abs-pos frames relative to the canvas is bug 425432.
|
||||
if (aLastRS->ComputedWidth() != NS_UNCONSTRAINEDSIZE && !isCanvasBlock) {
|
||||
if (aLastRS->ComputedWidth() != NS_UNCONSTRAINEDSIZE) {
|
||||
cbSize.width = PR_MAX(0,
|
||||
aLastRS->ComputedWidth() + aLastRS->mComputedPadding.LeftRight() - scrollbars.LeftRight());
|
||||
}
|
||||
if (aLastRS->ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
|
||||
// XXX This can be terribly wrong if we're the root element's block,
|
||||
// because our margin and borders will be included in the height
|
||||
// here but the abs-pos element(s) are positioned relative to
|
||||
// our content rect...
|
||||
cbSize.height = PR_MAX(0,
|
||||
aLastRS->ComputedHeight() + aLastRS->mComputedPadding.TopBottom() - scrollbars.TopBottom());
|
||||
}
|
||||
|
@ -1592,6 +1592,9 @@ nsContainerFrame::List(FILE* out, PRInt32 aIndent) const
|
||||
PRInt32 listIndex = 0;
|
||||
PRBool outputOneList = PR_FALSE;
|
||||
do {
|
||||
if (!outputOneList) {
|
||||
fputs("\n", out);
|
||||
}
|
||||
nsIFrame* kid = GetFirstChild(listName);
|
||||
if (nsnull != kid) {
|
||||
if (outputOneList) {
|
||||
|
@ -5561,12 +5561,19 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
|
||||
parent = parent->GetParent();
|
||||
} while (parent);
|
||||
|
||||
// We can get here if aProspectiveParent is the scrollframe for a viewport
|
||||
// and the kids are the anonymous scrollbars.
|
||||
NS_ASSERTION(aProspectiveParent->GetStyleContext()->GetPseudoType() ==
|
||||
nsCSSAnonBoxes::viewportScroll,
|
||||
if (aProspectiveParent->GetStyleContext()->GetPseudoType() ==
|
||||
nsCSSAnonBoxes::viewportScroll) {
|
||||
// aProspectiveParent is the scrollframe for a viewport
|
||||
// and the kids are the anonymous scrollbars
|
||||
return aProspectiveParent;
|
||||
}
|
||||
|
||||
// We can get here if the root element is absolutely positioned.
|
||||
// We can't test for this very accurately, but it can only happen
|
||||
// when the prospective parent is a canvas frame.
|
||||
NS_ASSERTION(aProspectiveParent->GetType() == nsGkAtoms::canvasFrame,
|
||||
"Should have found a parent before this");
|
||||
return aProspectiveParent;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
|
||||
// for focus
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
@ -67,6 +68,8 @@
|
||||
//#define DEBUG_CANVAS_FOCUS
|
||||
#endif
|
||||
|
||||
#define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
|
||||
|
||||
// Interface IDs
|
||||
|
||||
/**
|
||||
@ -81,7 +84,8 @@ class CanvasFrame : public nsHTMLContainerFrame,
|
||||
public nsICanvasFrame {
|
||||
public:
|
||||
CanvasFrame(nsStyleContext* aContext)
|
||||
: nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE) {}
|
||||
: nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE),
|
||||
mAbsoluteContainer(nsGkAtoms::absoluteList) {}
|
||||
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
@ -91,6 +95,8 @@ public:
|
||||
nsIFrame* aPrevInFlow);
|
||||
virtual void Destroy();
|
||||
|
||||
NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendFrames(nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIAtom* aListName,
|
||||
@ -99,6 +105,9 @@ public:
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
|
||||
virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
|
||||
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
@ -106,6 +115,11 @@ public:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
virtual PRBool IsContainingBlock() const { return PR_TRUE; }
|
||||
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
|
||||
{
|
||||
return nsHTMLContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eCanContainOverflowContainers));
|
||||
}
|
||||
|
||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -128,6 +142,21 @@ public:
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
virtual nsresult StealFrame(nsPresContext* aPresContext,
|
||||
nsIFrame* aChild,
|
||||
PRBool aForceNormal)
|
||||
{
|
||||
NS_ASSERTION(!aForceNormal, "No-one should be passing this in here");
|
||||
|
||||
// CanvasFrame keeps overflow container continuations of its child
|
||||
// frame in main child list
|
||||
nsresult rv = nsContainerFrame::StealFrame(aPresContext, aChild, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = nsContainerFrame::StealFrame(aPresContext, aChild);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
#endif
|
||||
@ -141,8 +170,9 @@ protected:
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
// Data members
|
||||
PRPackedBool mDoPaintFocus;
|
||||
nsCOMPtr<nsIViewManager> mViewManager;
|
||||
PRPackedBool mDoPaintFocus;
|
||||
nsCOMPtr<nsIViewManager> mViewManager;
|
||||
nsAbsoluteContainingBlock mAbsoluteContainer;
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
@ -198,6 +228,8 @@ CanvasFrame::Init(nsIContent* aContent,
|
||||
void
|
||||
CanvasFrame::Destroy()
|
||||
{
|
||||
mAbsoluteContainer.DestroyFrames(this);
|
||||
|
||||
nsIScrollableView* scrollingView = nsnull;
|
||||
mViewManager->GetRootScrollableView(&scrollingView);
|
||||
if (scrollingView) {
|
||||
@ -246,20 +278,32 @@ CanvasFrame::SetHasFocus(PRBool aHasFocus)
|
||||
{
|
||||
if (mDoPaintFocus != aHasFocus) {
|
||||
mDoPaintFocus = aHasFocus;
|
||||
nsIViewManager* vm = PresContext()->PresShell()->GetViewManager();
|
||||
if (vm) {
|
||||
vm->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
|
||||
}
|
||||
mViewManager->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasFrame::SetInitialChildList(nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
|
||||
|
||||
NS_ASSERTION(aListName || !aChildList || !aChildList->GetNextSibling(),
|
||||
"Primary child list can have at most one frame in it");
|
||||
return nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasFrame::AppendFrames(nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
|
||||
if (aListName) {
|
||||
@ -292,6 +336,9 @@ CanvasFrame::InsertFrames(nsIAtom* aListName,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame, aFrameList);
|
||||
|
||||
// Because we only support a single child frame inserting is the same
|
||||
// as appending
|
||||
NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
|
||||
@ -310,6 +357,9 @@ CanvasFrame::RemoveFrame(nsIAtom* aListName,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
if (aListName) {
|
||||
// We only support the unnamed principal child list
|
||||
@ -335,6 +385,24 @@ CanvasFrame::RemoveFrame(nsIAtom* aListName,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
CanvasFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
||||
{
|
||||
if (CANVAS_ABS_POS_CHILD_LIST == aIndex)
|
||||
return nsGkAtoms::absoluteList;
|
||||
|
||||
return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
CanvasFrame::GetFirstChild(nsIAtom* aListName) const
|
||||
{
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.GetFirstChild();
|
||||
|
||||
return nsHTMLContainerFrame::GetFirstChild(aListName);
|
||||
}
|
||||
|
||||
nsRect CanvasFrame::CanvasArea() const
|
||||
{
|
||||
nsRect result(GetOverflowRect());
|
||||
@ -419,6 +487,13 @@ CanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (GetPrevInFlow()) {
|
||||
DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
|
||||
}
|
||||
|
||||
aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetFirstChild(), aDirtyRect);
|
||||
|
||||
// Force a background to be shown. We may have a background propagated to us,
|
||||
// in which case GetStyleBackground wouldn't have the right background
|
||||
// and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
|
||||
@ -432,8 +507,8 @@ CanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsIFrame* kid = GetFirstChild(nsnull);
|
||||
if (kid) {
|
||||
nsIFrame* kid;
|
||||
for (kid = GetFirstChild(nsnull); kid; kid = kid->GetNextSibling()) {
|
||||
// Put our child into its own pseudo-stack.
|
||||
rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists,
|
||||
DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT);
|
||||
@ -528,7 +603,7 @@ CanvasFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
@ -540,7 +615,28 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Reflow our one and only child frame
|
||||
CanvasFrame* prevCanvasFrame = static_cast<CanvasFrame*>
|
||||
(GetPrevInFlow());
|
||||
if (prevCanvasFrame) {
|
||||
nsIFrame* overflow = prevCanvasFrame->GetOverflowFrames(aPresContext, PR_TRUE);
|
||||
if (overflow) {
|
||||
NS_ASSERTION(!overflow->GetNextSibling(),
|
||||
"must have doc root as canvas frame's only child");
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, overflow, prevCanvasFrame, this);
|
||||
// Prepend overflow to the our child list. There may already be
|
||||
// children placeholders for fixed-pos elements, which don't get
|
||||
// reflowed but must not be lost until the canvas frame is destroyed.
|
||||
mFrames.InsertFrames(this, nsnull, overflow);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow our one and only normal child frame. It's either the root
|
||||
// element's frame or a placeholder for that frame, if the root element
|
||||
// is abs-pos or fixed-pos. We may have additional children which
|
||||
// are placeholders for continuations of fixed-pos content, but those
|
||||
// don't need to be reflowed. The normal child is always comes before
|
||||
// the fixed-pos placeholders, because we insert it at the start
|
||||
// of the child list, above.
|
||||
nsHTMLReflowMetrics kidDesiredSize;
|
||||
if (mFrames.IsEmpty()) {
|
||||
// We have no child frame, so return an empty size
|
||||
@ -549,11 +645,9 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
PRBool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
|
||||
|
||||
// We must specify an unconstrained available height, because constrained
|
||||
// is only for when we're paginated...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
|
||||
nsSize(aReflowState.availableWidth,
|
||||
NS_UNCONSTRAINEDSIZE));
|
||||
aReflowState.availableHeight));
|
||||
|
||||
if (aReflowState.mFlags.mVResize &&
|
||||
(kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
|
||||
@ -561,16 +655,44 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
// hack for framesets.
|
||||
kidReflowState.mFlags.mVResize = PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
nsPoint kidPt(kidReflowState.mComputedMargin.left,
|
||||
kidReflowState.mComputedMargin.top);
|
||||
// Apply CSS relative positioning
|
||||
const nsStyleDisplay* styleDisp = kidFrame->GetStyleDisplay();
|
||||
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
|
||||
kidPt += nsPoint(kidReflowState.mComputedOffsets.left,
|
||||
kidReflowState.mComputedOffsets.top);
|
||||
}
|
||||
|
||||
// Reflow the frame
|
||||
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
||||
kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
|
||||
0, aStatus);
|
||||
kidPt.x, kidPt.y, 0, aStatus);
|
||||
|
||||
// Complete the reflow and position and size the child frame
|
||||
FinishReflowChild(kidFrame, aPresContext, &kidReflowState, kidDesiredSize,
|
||||
kidReflowState.mComputedMargin.left,
|
||||
kidReflowState.mComputedMargin.top, 0);
|
||||
kidPt.x, kidPt.y, 0);
|
||||
|
||||
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
|
||||
nsIFrame* nextFrame = kidFrame->GetNextInFlow();
|
||||
NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
|
||||
"If it's incomplete and has no nif yet, it must flag a nif reflow.");
|
||||
if (!nextFrame) {
|
||||
nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
|
||||
this, kidFrame, nextFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
kidFrame->SetNextSibling(nextFrame->GetNextSibling());
|
||||
nextFrame->SetNextSibling(nsnull);
|
||||
SetOverflowFrames(aPresContext, nextFrame);
|
||||
// Root overflow containers will be normal children of
|
||||
// the canvas frame, but that's ok because there
|
||||
// aren't any other frames we need to isolate them from
|
||||
// during reflow.
|
||||
}
|
||||
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
|
||||
nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
||||
}
|
||||
}
|
||||
|
||||
// If the child frame was just inserted, then we're responsible for making sure
|
||||
// it repaints
|
||||
@ -586,20 +708,35 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
|
||||
viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
|
||||
}
|
||||
|
||||
|
||||
// Return our desired size (which doesn't matter)
|
||||
aDesiredSize.width = aReflowState.availableWidth;
|
||||
aDesiredSize.height = kidDesiredSize.height +
|
||||
kidReflowState.mComputedMargin.TopBottom();
|
||||
aDesiredSize.width = aReflowState.ComputedWidth();
|
||||
aDesiredSize.height = aReflowState.ComputedHeight();
|
||||
|
||||
aDesiredSize.mOverflowArea.UnionRect(
|
||||
nsRect(0, 0, aDesiredSize.width, aDesiredSize.height),
|
||||
kidDesiredSize.mOverflowArea +
|
||||
nsPoint(kidReflowState.mComputedMargin.left,
|
||||
kidReflowState.mComputedMargin.top));
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
kidDesiredSize.mOverflowArea + kidPt);
|
||||
|
||||
if (mAbsoluteContainer.HasAbsoluteFrames()) {
|
||||
PRBool widthChanged = aDesiredSize.width != mRect.width;
|
||||
PRBool heightChanged = aDesiredSize.height != mRect.height;
|
||||
nsRect absPosBounds;
|
||||
mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
|
||||
aDesiredSize.width, aDesiredSize.height,
|
||||
PR_TRUE, widthChanged, heightChanged,
|
||||
&absPosBounds);
|
||||
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, absPosBounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (prevCanvasFrame) {
|
||||
ReflowOverflowContainerChildren(aPresContext, aReflowState,
|
||||
aDesiredSize.mOverflowArea, 0,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
|
||||
NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus);
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||
return NS_OK;
|
||||
|
@ -113,31 +113,24 @@ NS_NewTableCellInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
|
||||
return NS_NewBlockFrame(aPresShell, aContext);
|
||||
}
|
||||
|
||||
// This type of AreaFrame is the document root, a margin root, and the
|
||||
// initial containing block for absolutely positioned elements
|
||||
inline nsIFrame*
|
||||
NS_NewDocumentElementFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
|
||||
return NS_NewAreaFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
}
|
||||
|
||||
// This type of AreaFrame is a margin root, but does not shrink wrap
|
||||
// This type of BlockFrame is a margin root, but does not shrink wrap
|
||||
inline nsIFrame*
|
||||
NS_NewAbsoluteItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
|
||||
return NS_NewAreaFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
return NS_NewBlockFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
}
|
||||
|
||||
// This type of AreaFrame shrink wraps
|
||||
// This type of BlockFrame shrink wraps
|
||||
inline nsIFrame*
|
||||
NS_NewFloatingItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
|
||||
return NS_NewAreaFrame(aPresShell, aContext,
|
||||
return NS_NewBlockFrame(aPresShell, aContext,
|
||||
NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
}
|
||||
|
||||
// This type of AreaFrame doesn't use its own space manager and
|
||||
// This type of BlockFrame doesn't use its own space manager and
|
||||
// doesn't shrink wrap.
|
||||
inline nsIFrame*
|
||||
NS_NewRelativeItemWrapperFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags) {
|
||||
return NS_NewAreaFrame(aPresShell, aContext, aFlags);
|
||||
return NS_NewBlockFrame(aPresShell, aContext, aFlags);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -1531,25 +1531,7 @@ nsHTMLReflowState::ComputeContainingBlockRectangle(nsPresContext* aPres
|
||||
// If the ancestor is block-level, the containing block is formed by the
|
||||
// padding edge of the ancestor
|
||||
aContainingBlockWidth += aContainingBlockRS->mComputedPadding.LeftRight();
|
||||
|
||||
// If the containing block is the initial containing block and it has a
|
||||
// height that depends on its content, then use the viewport height instead.
|
||||
// This gives us a reasonable value against which to compute percentage
|
||||
// based heights and to do bottom relative positioning
|
||||
if ((NS_AUTOHEIGHT == aContainingBlockHeight) &&
|
||||
nsLayoutUtils::IsInitialContainingBlock(aContainingBlockRS->frame)) {
|
||||
|
||||
// Use the viewport height as the containing block height
|
||||
const nsHTMLReflowState* rs = aContainingBlockRS->parentReflowState;
|
||||
while (rs) {
|
||||
aContainingBlockHeight = rs->mComputedHeight;
|
||||
rs = rs->parentReflowState;
|
||||
}
|
||||
|
||||
} else {
|
||||
aContainingBlockHeight +=
|
||||
aContainingBlockRS->mComputedPadding.TopBottom();
|
||||
}
|
||||
aContainingBlockHeight += aContainingBlockRS->mComputedPadding.TopBottom();
|
||||
}
|
||||
} else {
|
||||
// an element in quirks mode gets a containing block based on looking for a
|
||||
|
@ -1073,11 +1073,8 @@ nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
||||
nsIFrame*
|
||||
nsPositionedInlineFrame::GetFirstChild(nsIAtom* aListName) const
|
||||
{
|
||||
if (nsGkAtoms::absoluteList == aListName) {
|
||||
nsIFrame* result = nsnull;
|
||||
mAbsoluteContainer.FirstChild(this, aListName, &result);
|
||||
return result;
|
||||
}
|
||||
if (nsGkAtoms::absoluteList == aListName)
|
||||
return mAbsoluteContainer.GetFirstChild();
|
||||
|
||||
return nsInlineFrame::GetFirstChild(aListName);
|
||||
}
|
||||
|
@ -69,55 +69,6 @@ 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,
|
||||
@ -129,67 +80,27 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
|
||||
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;
|
||||
// Also we need to avoid repeating the call to ReplicateFixedFrames.
|
||||
nsPageContentFrame* prevPageContentFrame = static_cast<nsPageContentFrame*>
|
||||
(GetPrevInFlow());
|
||||
if (mFrames.IsEmpty() && prevPageContentFrame) {
|
||||
// Pull the doc root frame's continuation and copy fixed frames.
|
||||
nsIFrame* overflow = prevPageContentFrame->GetOverflowFrames(aPresContext, PR_TRUE);
|
||||
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);
|
||||
if (GetPrevInFlow() && (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||
nsresult rv = aPresContext->PresShell()->FrameConstructor()
|
||||
->ReplicateFixedFrames(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// A PageContentFrame must always have one child: the canvas frame.
|
||||
// Resize our frame allowing it only to be as big as we are
|
||||
// XXX Pay attention to the page's border and padding...
|
||||
if (mFrames.NotEmpty()) {
|
||||
nsIFrame* frame = mFrames.FirstChild();
|
||||
nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
|
||||
kidReflowState.SetComputedHeight(aReflowState.availableHeight);
|
||||
|
||||
mPD->mPageContentSize = aReflowState.availableWidth;
|
||||
|
||||
// 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();
|
||||
NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
|
||||
"If it's incomplete and has no nif yet, it must flag a nif reflow.");
|
||||
if (!nextFrame) {
|
||||
nsresult rv = nsHTMLContainerFrame::CreateNextInFlow(aPresContext,
|
||||
this, frame, nextFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
frame->SetNextSibling(nextFrame->GetNextSibling());
|
||||
nextFrame->SetNextSibling(nsnull);
|
||||
SetOverflowFrames(aPresContext, nextFrame);
|
||||
// Root overflow containers will be normal children of
|
||||
// the pageContentFrame, but that's ok because there
|
||||
// aren't any other frames we need to isolate them from
|
||||
// during reflow.
|
||||
}
|
||||
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
|
||||
nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
||||
}
|
||||
}
|
||||
|
||||
// The document element's background should cover the entire canvas, so
|
||||
// take into account the combined area and any space taken up by
|
||||
// absolutely positioned elements
|
||||
|
@ -83,10 +83,6 @@ protected:
|
||||
nsPageContentFrame(nsStyleContext* aContext) : ViewportFrame(aContext) {}
|
||||
|
||||
nsSharedPageData* mPD;
|
||||
|
||||
private:
|
||||
PRBool IsFixedPlaceholder(nsIFrame* aFrame);
|
||||
nsFrameList StealFixedPlaceholders(nsIFrame* aDocRoot);
|
||||
};
|
||||
|
||||
#endif /* nsPageContentFrame_h___ */
|
||||
|
@ -179,11 +179,8 @@ ViewportFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
||||
nsIFrame*
|
||||
ViewportFrame::GetFirstChild(nsIAtom* aListName) const
|
||||
{
|
||||
if (nsGkAtoms::fixedList == aListName) {
|
||||
nsIFrame* result = nsnull;
|
||||
mFixedContainer.FirstChild(this, aListName, &result);
|
||||
return result;
|
||||
}
|
||||
if (nsGkAtoms::fixedList == aListName)
|
||||
return mFixedContainer.GetFirstChild();
|
||||
|
||||
return nsContainerFrame::GetFirstChild(aListName);
|
||||
}
|
||||
@ -309,8 +306,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsIFrame* f;
|
||||
mFixedContainer.FirstChild(this, nsGkAtoms::fixedList, &f);
|
||||
nsIFrame* f = mFixedContainer.GetFirstChild();
|
||||
NS_ASSERTION(!f || (offset.x == 0 && offset.y == 0),
|
||||
"We don't handle correct positioning of fixed frames with "
|
||||
"scrollbars in odd positions");
|
||||
|
5
layout/reftests/bugs/243519-9f.html
Normal file
5
layout/reftests/bugs/243519-9f.html
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html style="position:relative; height:50%;">
|
||||
<body style="position:absolute; width:50%; top:50px; left:50px; height:100%; margin:0; border:10px solid black;">
|
||||
</body>
|
||||
</html>
|
@ -125,6 +125,7 @@ fails == 25888-3r.html 25888-3r-ref.html # bug 25888
|
||||
== 180085-1.html 180085-1-ref.html
|
||||
== 180085-2.html 180085-2-ref.html
|
||||
== 185388-1.html 185388-1-ref.html
|
||||
!= 200774-1.html about:blank # really a crashtest
|
||||
== 201215-1.html 201215-1-ref.html
|
||||
== 201293-1a.html 201293-1-ref.html
|
||||
== 201293-1b.html 201293-1-ref.html
|
||||
@ -166,6 +167,28 @@ fails == 25888-3r.html 25888-3r-ref.html # bug 25888
|
||||
== 240470-1.html 240470-1-ref.html
|
||||
== 243266-1.html 243266-1-ref.html
|
||||
== 243302-1.html 243302-1-ref.html
|
||||
== 243519-1.html 243519-1-ref.html
|
||||
== 243519-2.html 243519-2-ref.html
|
||||
== 243519-3.html 243519-3-ref.html
|
||||
== 243519-4a.html 243519-4-ref.html
|
||||
== 243519-4b.html 243519-4-ref.html
|
||||
== 243519-4c.html 243519-4-ref.html
|
||||
== 243519-4d.html 243519-4-ref.html
|
||||
== 243519-4e.html 243519-4-ref.html
|
||||
== 243519-4f.html 243519-4-ref.html
|
||||
== 243519-5a.html 243519-5-ref.html
|
||||
== 243519-5b.html 243519-5-ref.html
|
||||
== 243519-5c.html 243519-5-ref.html
|
||||
== 243519-5d.html 243519-5-ref.html
|
||||
== 243519-6.html 243519-6-ref.html
|
||||
== 243519-7.html 243519-7-ref.html
|
||||
== 243519-8.svg 243519-8-ref.svg
|
||||
== 243519-9a.html 243519-9-ref.html
|
||||
== 243519-9b.html 243519-9-ref.html
|
||||
== 243519-9c.html 243519-9-ref.html
|
||||
== 243519-9d.html 243519-9-ref.html
|
||||
== 243519-9e.html 243519-9-ref.html
|
||||
== 243519-9f.html 243519-9-ref.html
|
||||
== 244135-1.html 244135-1-ref.html
|
||||
== 244135-2.html 244135-2-ref.html
|
||||
== 244932-1.html 244932-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user