Make blocks whose ancestors are not blocks have the NS_BLOCK_MARGIN_ROOT and

NS_BLOCK_SPACE_MGR bits as necessary.  Bug 354600, r+sr=roc
This commit is contained in:
bzbarsky%mit.edu 2007-02-18 23:53:25 +00:00
Родитель bbe056fa5f
Коммит fe88b5e467
10 изменённых файлов: 56 добавлений и 72 удалений

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

@ -12207,8 +12207,6 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
*aNewFrame = columnSetFrame;
columnSetFrame->SetInitialChildList(nsnull, blockFrame);
blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR);
}
blockFrame->SetStyleContextWithoutNotification(blockStyle);
@ -12225,13 +12223,6 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
// See if we need to create a view, e.g. the frame is absolutely positioned
nsHTMLContainerFrame::CreateViewForFrame(blockFrame, contentParent, PR_FALSE);
// If we're the first block to be created (e.g., because we're
// contained inside a XUL document), then make sure that we've got a
// space manager so we can handle floats...
if (! aState.mFloatedItems.containingBlock) {
blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
}
// We should make the outer frame be the absolute containing block,
// if one is required. We have to do this because absolute
// positioning must be computed with respect to the CSS dimensions
@ -12378,10 +12369,6 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
blockFrame = NS_NewBlockFrame(mPresShell, blockSC);
}
if (! aState.mFloatedItems.containingBlock) {
blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
}
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, blockFrame, PR_FALSE);
// Any inline frame could have a view (e.g., opacity)

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

@ -1037,20 +1037,10 @@ nsComboboxControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
return NS_OK;
}
// XXXbz this is a for-now hack until display:inline-block works.
class nsComboboxDisplayFrame;
static nsComboboxDisplayFrame*
NS_NewComboboxDisplayFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
nsComboboxControlFrame* aComboBox);
// XXXbz this is a for-now hack. Now that display:inline-block works,
// need to revisit this.
class nsComboboxDisplayFrame : public nsBlockFrame {
public:
friend nsComboboxDisplayFrame*
NS_NewComboboxDisplayFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext,
nsComboboxControlFrame* aComboBox);
nsComboboxDisplayFrame (nsStyleContext* aContext,
nsComboboxControlFrame* aComboBox)
: nsBlockFrame(aContext),
@ -1097,20 +1087,6 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext,
return nsBlockFrame::Reflow(aPresContext, aDesiredSize, state, aStatus);
}
static nsComboboxDisplayFrame*
NS_NewComboboxDisplayFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
nsComboboxControlFrame* aComboBox)
{
nsComboboxDisplayFrame* it =
new (aPresShell) nsComboboxDisplayFrame(aContext, aComboBox);
if (it) {
it->SetFlags(NS_BLOCK_SPACE_MGR);
}
return it;
}
nsIFrame*
nsComboboxControlFrame::CreateFrameFor(nsIContent* aContent)
{
@ -1144,7 +1120,7 @@ nsComboboxControlFrame::CreateFrameFor(nsIContent* aContent)
}
// Start by by creating our anonymous block frame
mDisplayFrame = NS_NewComboboxDisplayFrame(shell, styleContext, this);
mDisplayFrame = new (shell) nsComboboxDisplayFrame(styleContext, this);
if (NS_UNLIKELY(!mDisplayFrame)) {
return nsnull;
}

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

@ -849,7 +849,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// than keeping it around only during reflow then we should create it
// only when there are actually floats to manage. Otherwise things
// like tables will gain significant bloat.
if (NS_BLOCK_SPACE_MGR & mState)
PRBool needSpaceManager = nsBlockFrame::BlockNeedsSpaceManager(this);
if (needSpaceManager)
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
// OK, some lines may be reflowed. Blow away any saved line cursor because
@ -871,9 +872,9 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
return NS_OK;
}
PRBool marginRoot = BlockIsMarginRoot(this);
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
(NS_BLOCK_MARGIN_ROOT & mState),
(NS_BLOCK_MARGIN_ROOT & mState));
marginRoot, marginRoot, needSpaceManager);
#ifdef IBMBIDI
if (! mLines.empty()) {
@ -1126,7 +1127,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// Clear the space manager pointer in the block reflow state so we
// don't waste time translating the coordinate system back on a dead
// space manager.
if (NS_BLOCK_SPACE_MGR & mState)
if (needSpaceManager)
state.mSpaceManager = nsnull;
aStatus = state.mReflowStatus;
@ -1299,7 +1300,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
}
}
if (NS_BLOCK_SPACE_MGR & mState) {
if (aState.GetFlag(BRS_SPACE_MGR)) {
// Include the space manager's state to properly account for the
// bottom margin of any floated elements; e.g., inside a table cell.
nscoord ymost;
@ -5907,9 +5908,6 @@ nsBlockFrame::Init(nsIContent* aContent,
nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow);
if (IsBoxWrapped())
mState |= NS_BLOCK_SPACE_MGR;
return rv;
}
@ -6278,17 +6276,37 @@ nsBlockFrame::CheckFloats(nsBlockReflowState& aState)
}
}
NS_IMETHODIMP
nsBlockFrame::SetParent(const nsIFrame* aParent)
/* static */
PRBool
nsBlockFrame::BlockIsMarginRoot(nsIFrame* aBlock)
{
nsresult rv = nsBlockFrameSuper::SetParent(aParent);
if (IsBoxWrapped())
mState |= NS_BLOCK_SPACE_MGR;
NS_PRECONDITION(aBlock, "Must have a frame");
#ifdef DEBUG
nsBlockFrame* blockFrame;
aBlock->QueryInterface(kBlockFrameCID, (void**)&blockFrame);
NS_ASSERTION(blockFrame, "aBlock must be a block");
#endif
// XXX should we clear NS_BLOCK_SPACE_MGR if we were the child of a box
// but no longer are?
nsIFrame* parent = aBlock->GetParent();
return (aBlock->GetStateBits() & NS_BLOCK_MARGIN_ROOT) ||
(parent && !parent->IsFloatContainingBlock() &&
parent->GetType() != nsGkAtoms::columnSetFrame);
}
return rv;
/* static */
PRBool
nsBlockFrame::BlockNeedsSpaceManager(nsIFrame* aBlock)
{
NS_PRECONDITION(aBlock, "Must have a frame");
#ifdef DEBUG
nsBlockFrame* blockFrame;
aBlock->QueryInterface(kBlockFrameCID, (void**)&blockFrame);
NS_ASSERTION(blockFrame, "aBlock must be a block");
#endif
nsIFrame* parent = aBlock->GetParent();
return (aBlock->GetStateBits() & NS_BLOCK_SPACE_MGR) ||
(parent && !parent->IsFloatContainingBlock());
}
// XXX keep the text-run data in the first-in-flow of the block

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

@ -173,7 +173,6 @@ public:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
NS_IMETHOD SetParent(const nsIFrame* aParent);
virtual nscoord GetBaseline() const;
virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
virtual void Destroy();
@ -277,6 +276,9 @@ public:
PRBool HandleOverflowPlaceholdersOnPulledLine(
nsBlockReflowState& aState, nsLineBox* aLine);
static PRBool BlockIsMarginRoot(nsIFrame* aBlock);
static PRBool BlockNeedsSpaceManager(nsIFrame* aBlock);
protected:
nsBlockFrame(nsStyleContext* aContext)
: nsHTMLContainerFrame(aContext)

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

@ -114,8 +114,8 @@ nsBlockReflowContext::ComputeCollapsedTopMargin(const nsHTMLReflowState& aRS,
nsIFrame* frame = DescendIntoBlockLevelFrame(aRS.frame);
nsPresContext* prescontext = frame->GetPresContext();
if (0 == aRS.mComputedBorderPadding.top &&
!(frame->GetStateBits() & NS_BLOCK_MARGIN_ROOT) &&
NS_SUCCEEDED(frame->QueryInterface(kBlockFrameCID, &bf))) {
NS_SUCCEEDED(frame->QueryInterface(kBlockFrameCID, &bf)) &&
!nsBlockFrame::BlockIsMarginRoot(frame)) {
// iterate not just through the lines of 'block' but also its
// overflow lines and the normal and overflow lines of its next in
// flows. Note that this will traverse some frames more than once:

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

@ -63,7 +63,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
nsBlockFrame* aFrame,
const nsHTMLReflowMetrics& aMetrics,
PRBool aTopMarginRoot,
PRBool aBottomMarginRoot)
PRBool aBottomMarginRoot,
PRBool aBlockNeedsSpaceManager)
: mBlock(aFrame),
mPresContext(aPresContext),
mReflowState(aReflowState),
@ -85,6 +86,9 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
if (GetFlag(BRS_ISTOPMARGINROOT)) {
SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
}
if (aBlockNeedsSpaceManager) {
SetFlag(BRS_SPACE_MGR, PR_TRUE);
}
mSpaceManager = aReflowState.mSpaceManager;
@ -346,8 +350,7 @@ nsBlockReflowState::ReconstructMarginAbove(nsLineList::iterator aLine)
if (aLine == firstLine) {
// If the top margin was carried out (and thus already applied),
// set it to zero. Either way, we're done.
if ((0 == mReflowState.mComputedBorderPadding.top) &&
!(block->mState & NS_BLOCK_MARGIN_ROOT)) {
if (!GetFlag(BRS_ISTOPMARGINROOT)) {
mPrevBottomMargin.Zero();
}
break;
@ -401,7 +404,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
// don't recover any state inside a block that has its own space
// manager (we don't currently have any blocks like this, though,
// thanks to our use of extra frames for 'overflow')
if (kid && !(kid->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
if (kid && !nsBlockFrame::BlockNeedsSpaceManager(kid)) {
nscoord tx = kid->mRect.x, ty = kid->mRect.y;
// If the element is relatively positioned, then adjust x and y

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

@ -57,7 +57,9 @@ class nsBlockFrame;
#define BRS_ISFIRSTINFLOW 0x00000010
// Set when mLineAdjacentToTop is valid
#define BRS_HAVELINEADJACENTTOTOP 0x00000020
#define BRS_LASTFLAG BRS_HAVELINEADJACENTTOTOP
// Set when the block has the equivalent of NS_BLOCK_SPACE_MGR
#define BRS_SPACE_MGR 0x00000040
#define BRS_LASTFLAG BRS_SPACE_MGR
class nsBlockReflowState {
public:
@ -65,7 +67,8 @@ public:
nsPresContext* aPresContext,
nsBlockFrame* aFrame,
const nsHTMLReflowMetrics& aMetrics,
PRBool aTopMarginRoot, PRBool aBottomMarginRoot);
PRBool aTopMarginRoot, PRBool aBottomMarginRoot,
PRBool aBlockNeedsSpaceManager);
~nsBlockReflowState();

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

@ -507,8 +507,6 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
NS_NOTREACHED("Couldn't create continuation");
break;
}
kidNextInFlow->AddStateBits(NS_BLOCK_SPACE_MGR);
}
if (columnCount >= aConfig.mBalanceColCount) {

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

@ -99,7 +99,7 @@ NS_NewAreaFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFl
// These AreaFrame's shrink wrap around their contents
inline nsIFrame*
NS_NewTableCellInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) {
return NS_NewBlockFrame(aPresShell, aContext, NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT);
return NS_NewBlockFrame(aPresShell, aContext);
}
// This type of AreaFrame is the document root, a margin root, and the

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

@ -305,10 +305,7 @@ public:
virtual PRBool IsFrameOfType(PRUint32 aFlags) const;
protected:
nsMathMLmtdInnerFrame(nsStyleContext* aContext) : nsBlockFrame(aContext) {
// Set the right bits -- see what NS_NewTableCellInnerFrame does
AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
}
nsMathMLmtdInnerFrame(nsStyleContext* aContext) : nsBlockFrame(aContext) {}
virtual ~nsMathMLmtdInnerFrame();
virtual PRIntn GetSkipSides() const { return 0; }