зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
bbe056fa5f
Коммит
fe88b5e467
|
@ -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; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче