From f03bac09cc211711a1a741317c42b0c2197e0305 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Fri, 18 Mar 2005 04:13:05 +0000 Subject: [PATCH] Add an IsFloatContainingBlock() method on nsIFrame, use this in the frame constructor. Make sure the div inside an when we do our "we need a plugin" thing has the space manager bit set. Bug 283385, bug 285165, bug 286111. r+sr=roc --- layout/base/nsCSSFrameConstructor.cpp | 76 ++++++++++++++------------- layout/generic/nsBlockFrame.cpp | 7 ++- layout/generic/nsBlockFrame.h | 1 + layout/generic/nsIFrame.h | 10 +++- layout/generic/nsObjectFrame.cpp | 3 ++ layout/style/html.css | 7 --- 6 files changed, 58 insertions(+), 46 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 2829b3edc110..87afeb03a83c 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1232,6 +1232,12 @@ nsFrameConstructorState::PushFloatContainingBlock(nsIFrame* aNewFloatContainingB PRBool aFirstLetterStyle, PRBool aFirstLineStyle) { + // XXXbz we should probably just be able to assert that + // aNewFloatContainingBlock is a float containing block... see XXX comment at + // the top of ProcessChildren. + NS_PRECONDITION(aNewFloatContainingBlock->GetContentInsertionFrame()-> + IsFloatContainingBlock(), + "Please push a real float containing block!"); aSaveState.mItems = &mFloatedItems; aSaveState.mFirstLetterStyle = &mFirstLetterStyle; aSaveState.mFirstLineStyle = &mFirstLineStyle; @@ -1584,6 +1590,7 @@ AdjustFloatParentPtrs(nsIFrame* aFrame, // containing block has changed as the result of reparenting, nsIFrame *parent = aState.mFloatedItems.containingBlock; + NS_ASSERTION(parent, "Should have float containing block here!"); outOfFlowFrame->SetParent(parent); if (outOfFlowFrame->GetStateBits() & (NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) { @@ -1599,8 +1606,7 @@ AdjustFloatParentPtrs(nsIFrame* aFrame, return; } - // XXXbz we really want IsFloatContainingBlock() here! - if (IsBlockFrame(aFrame)) { + if (aFrame->IsFloatContainingBlock()) { // No need to recurse further; floats whose placeholders are // inside a block already have the right parent. return; @@ -4306,7 +4312,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState, if (NS_FAILED(rv)) { return rv; } - isBlockFrame = PR_TRUE; } else #endif @@ -6590,8 +6595,8 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsFrameConstructorState& aSta NS_NewFloatingItemWrapperFrame(mPresShell, &newFrame); rv = ConstructBlock(aState, aDisplay, aContent, - aState.mFloatedItems.containingBlock, aParentFrame, - aStyleContext, &newFrame, aFrameItems, + aState.GetGeometricParent(aDisplay, aParentFrame), + aParentFrame, aStyleContext, &newFrame, aFrameItems, aDisplay->mPosition == NS_STYLE_POSITION_RELATIVE); if (NS_FAILED(rv)) { return rv; @@ -7937,26 +7942,18 @@ nsCSSFrameConstructor::GetFloatContainingBlock(nsIFrame* aFrame) { NS_PRECONDITION(mInitialContainingBlock, "no initial containing block"); - // Starting with aFrame, look for a frame that is a real block frame - // XXXbz some frames are float containing blocks but not "real block frames". - // Perhaps we need to make more use of GetContentInsertionFrame() somewhere? - nsIFrame* containingBlock = aFrame; - while (nsnull != containingBlock) { - const nsStyleDisplay* display = containingBlock->GetStyleDisplay(); - if ((NS_STYLE_DISPLAY_BLOCK == display->mDisplay) || - (NS_STYLE_DISPLAY_LIST_ITEM == display->mDisplay)) { - break; + // Starting with aFrame, look for a frame that is a float containing block + for (nsIFrame* containingBlock = aFrame; + containingBlock; + containingBlock = containingBlock->GetParent()) { + if (containingBlock->IsFloatContainingBlock()) { + return containingBlock; } - // Continue walking up the hierarchy - containingBlock = containingBlock->GetParent(); } - // If we didn't find a containing block, then use the initial - // containing block - if (nsnull == containingBlock) { - containingBlock = mInitialContainingBlock; - } - return containingBlock; + // If we didn't find a containing block, then there just isn't + // one.... return null + return nsnull; } /** @@ -8637,13 +8634,15 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer, GetFloatContainingBlock(parentFrame)); // See if the containing block has :first-letter style applied. - PRBool haveFirstLetterStyle, haveFirstLineStyle; + PRBool haveFirstLetterStyle = PR_FALSE, haveFirstLineStyle = PR_FALSE; nsIFrame* containingBlock = state.mFloatedItems.containingBlock; - nsIContent* blockContent = containingBlock->GetContent(); - nsStyleContext* blockSC = containingBlock->GetStyleContext(); - HaveSpecialBlockStyle(blockContent, blockSC, - &haveFirstLetterStyle, - &haveFirstLineStyle); + if (containingBlock) { + nsIContent* blockContent = containingBlock->GetContent(); + nsStyleContext* blockSC = containingBlock->GetStyleContext(); + HaveSpecialBlockStyle(blockContent, blockSC, + &haveFirstLetterStyle, + &haveFirstLineStyle); + } if (haveFirstLetterStyle) { // Before we get going, remove the current letter frames @@ -9263,11 +9262,13 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer, (NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) || (NS_STYLE_DISPLAY_INLINE_BLOCK == parentDisplay->mDisplay)) { // Recover the special style flags for the containing block - blockSC = containingBlock->GetStyleContext(); - blockContent = containingBlock->GetContent(); - HaveSpecialBlockStyle(blockContent, blockSC, - &haveFirstLetterStyle, - &haveFirstLineStyle); + if (containingBlock) { + blockSC = containingBlock->GetStyleContext(); + blockContent = containingBlock->GetContent(); + HaveSpecialBlockStyle(blockContent, blockSC, + &haveFirstLetterStyle, + &haveFirstLineStyle); + } if (haveFirstLetterStyle) { // Get the correct parentFrame and prevSibling - if a @@ -9730,9 +9731,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, // Examine the containing-block for the removed content and see if // :first-letter style applies. nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame); - nsStyleContext* blockSC = containingBlock->GetStyleContext(); - nsIContent* blockContent = containingBlock->GetContent(); - PRBool haveFLS = HaveFirstLetterStyle(blockContent, blockSC); + PRBool haveFLS = containingBlock ? + HaveFirstLetterStyle(containingBlock->GetContent(), + containingBlock->GetStyleContext()) : + PR_FALSE; if (haveFLS) { // Trap out to special routine that handles adjusting a blocks // frame tree when first-letter style is present. @@ -11781,6 +11783,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, PRBool aParentIsBlock, nsTableCreator* aTableCreator) { + // XXXbz ideally, this would do all the pushing of various + // containing blocks as needed, so callers don't have to do it... nsresult rv = NS_OK; nsStyleContext* styleContext = aFrame->GetStyleContext(); diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 3acaaa0c4188..7e0544f11f98 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -537,6 +537,12 @@ nsBlockFrame::IsContainingBlock() const return PR_TRUE; } +/* virtual */ PRBool +nsBlockFrame::IsFloatContainingBlock() const +{ + return PR_TRUE; +} + ////////////////////////////////////////////////////////////////////// // Frame structure methods @@ -5524,7 +5530,6 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, // width. Reflow it again, this time pinning the width to the // maxElementWidth. availSpace.width = maxElementWidth; - nsCollapsingMargin marginMEW; // construct the html reflow state for the float. // ReflowBlock will initialize it. nsHTMLReflowState redoFloatRS(aState.mPresContext, aState.mReflowState, diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 105af185898e..f2334cdc58ff 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -132,6 +132,7 @@ public: NS_IMETHOD Destroy(nsPresContext* aPresContext); NS_IMETHOD IsSplittable(nsSplittableType& aIsSplittable) const; virtual PRBool IsContainingBlock() const; + virtual PRBool IsFloatContainingBlock() const; NS_IMETHOD Paint(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 2e8706029434..bdc99c500017 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -94,9 +94,9 @@ struct nsMargin; typedef class nsIFrame nsIBox; // IID for the nsIFrame interface -// c8f3532b-ed45-4812-8da9-2a1b0afe4179 +// 715842c9-8d33-41e9-8d71-78c81850c882 #define NS_IFRAME_IID \ - { 0xc8f3532b, 0xed45, 0x4812, { 0x8d, 0xa9, 0x2a, 0x1b, 0x0a, 0xfe, 0x41, 0x79 } } + { 0x715842c9, 0x8d33, 0x41e9, { 0x8d, 0x71, 0x78, 0xc8, 0x18, 0x50, 0xc8, 0x82 } } /** * Indication of how the frame can be split. This is used when doing runaround @@ -1060,6 +1060,12 @@ public: */ virtual PRBool IsContainingBlock() const = 0; + /** + * Is this frame a containing block for floating elements? + * Note that very few frames are, so default to false. + */ + virtual PRBool IsFloatContainingBlock() const { return PR_FALSE; } + /** * Does this frame want to capture the mouse when the user clicks in * it or its children? If so, return the view which should be diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 4d5909ff5617..b62a599c1d79 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -1623,6 +1623,9 @@ nsObjectFrame::CreateDefaultFrames(nsPresContext *aPresContext, if (NS_FAILED(rv)) break; + // Give it a space manager, so it won't crash of ancestors don't have one + divFrame->AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT); + nsHTMLContainerFrame::CreateViewForFrame(divFrame, this, PR_FALSE); mFrames.AppendFrame(this, divFrame); diff --git a/layout/style/html.css b/layout/style/html.css index 8099dcdfb6fd..cd4eaf8e2a46 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -87,13 +87,6 @@ center { text-align: -moz-center; } -legend { - /* HTML legend always builds an nsLegendFrame, - which is a block. The style system needs to - know. */ - display: block !important; -} - blockquote[type=cite] { display: block; margin: 1em 0px;