Bug 728911 - Remove the nsBlockFrame::mBullet member and store it in a frame property instead (as needed). For an outside bullet, store it as a nsFrameList* to support GetChildList(kBulletList). part 2/2 r=bz

This commit is contained in:
Mats Palmgren 2012-03-08 02:57:37 +01:00
parent 6b007e5ce3
commit d2745bc51c
3 changed files with 179 additions and 108 deletions

View File

@ -287,6 +287,9 @@ NS_DECLARE_FRAME_PROPERTY(OverflowOutOfFlowsProperty,
nsContainerFrame::DestroyFrameList) nsContainerFrame::DestroyFrameList)
NS_DECLARE_FRAME_PROPERTY(PushedFloatProperty, NS_DECLARE_FRAME_PROPERTY(PushedFloatProperty,
nsContainerFrame::DestroyFrameList) nsContainerFrame::DestroyFrameList)
NS_DECLARE_FRAME_PROPERTY(OutsideBulletProperty,
nsContainerFrame::DestroyFrameList)
NS_DECLARE_FRAME_PROPERTY(InsideBulletProperty, nsnull)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -310,12 +313,6 @@ void
nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot) nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
{ {
DestroyAbsoluteFrames(aDestructRoot); DestroyAbsoluteFrames(aDestructRoot);
// Outside bullets are not in our child-list so check for them here
// and delete them when present.
if (mBullet && HaveOutsideBullet()) {
mBullet->DestroyFrom(aDestructRoot);
mBullet = nsnull;
}
mFloats.DestroyFramesFrom(aDestructRoot); mFloats.DestroyFramesFrom(aDestructRoot);
@ -599,9 +596,10 @@ nsBlockFrame::GetChildList(ChildListID aListID) const
const nsFrameList* list = GetPushedFloats(); const nsFrameList* list = GetPushedFloats();
return list ? *list : nsFrameList::EmptyList(); return list ? *list : nsFrameList::EmptyList();
} }
case kBulletList: case kBulletList: {
return HaveOutsideBullet() ? nsFrameList(mBullet, mBullet) const nsFrameList* list = GetOutsideBulletList();
: nsFrameList::EmptyList(); return list ? *list : nsFrameList::EmptyList();
}
default: default:
return nsContainerFrame::GetChildList(aListID); return nsContainerFrame::GetChildList(aListID);
} }
@ -620,9 +618,9 @@ nsBlockFrame::GetChildLists(nsTArray<ChildList>* aLists) const
list->AppendIfNonempty(aLists, kOverflowOutOfFlowList); list->AppendIfNonempty(aLists, kOverflowOutOfFlowList);
} }
mFloats.AppendIfNonempty(aLists, kFloatList); mFloats.AppendIfNonempty(aLists, kFloatList);
if (HaveOutsideBullet()) { list = GetOutsideBulletList();
nsFrameList bullet(mBullet, mBullet); if (list) {
bullet.AppendIfNonempty(aLists, kBulletList); list->AppendIfNonempty(aLists, kBulletList);
} }
list = GetPushedFloats(); list = GetPushedFloats();
if (list) { if (list) {
@ -1111,7 +1109,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// rare case: an empty first line followed by a second line that // rare case: an empty first line followed by a second line that
// contains a block (example: <LI>\n<P>... ). This is where // contains a block (example: <LI>\n<P>... ). This is where
// the second case can happen. // the second case can happen.
if (mBullet && HaveOutsideBullet() && !mLines.empty() && if (HasOutsideBullet() && !mLines.empty() &&
(mLines.front()->IsBlock() || (mLines.front()->IsBlock() ||
(0 == mLines.front()->mBounds.height && (0 == mLines.front()->mBounds.height &&
mLines.front() != mLines.back() && mLines.front() != mLines.back() &&
@ -1123,7 +1121,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
bool havePosition = nsLayoutUtils::GetFirstLinePosition(this, &position); bool havePosition = nsLayoutUtils::GetFirstLinePosition(this, &position);
nscoord lineTop = havePosition ? position.mTop nscoord lineTop = havePosition ? position.mTop
: reflowState->mComputedBorderPadding.top; : reflowState->mComputedBorderPadding.top;
ReflowBullet(state, metrics, lineTop); nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, state, metrics, lineTop);
NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0, NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0,
"empty bullet took up space"); "empty bullet took up space");
@ -1134,9 +1133,9 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// bullets that are placed next to a child block (bug 92896) // bullets that are placed next to a child block (bug 92896)
// Tall bullets won't look particularly nice here... // Tall bullets won't look particularly nice here...
nsRect bbox = mBullet->GetRect(); nsRect bbox = bullet->GetRect();
bbox.y = position.mBaseline - metrics.ascent; bbox.y = position.mBaseline - metrics.ascent;
mBullet->SetRect(bbox); bullet->SetRect(bbox);
} }
// Otherwise just leave the bullet where it is, up against our top padding. // Otherwise just leave the bullet where it is, up against our top padding.
} }
@ -1492,13 +1491,14 @@ nsBlockFrame::ComputeOverflowAreas(const nsRect& aBounds,
areas.UnionWith(line->GetOverflowAreas()); areas.UnionWith(line->GetOverflowAreas());
} }
// Factor the bullet in; normally the bullet will be factored into // Factor an outside bullet in; normally the bullet will be factored into
// the line-box's overflow areas. However, if the line is a block // the line-box's overflow areas. However, if the line is a block
// line then it won't; if there are no lines, it won't. So just // line then it won't; if there are no lines, it won't. So just
// factor it in anyway (it can't hurt if it was already done). // factor it in anyway (it can't hurt if it was already done).
// XXXldb Can we just fix GetOverflowArea instead? // XXXldb Can we just fix GetOverflowArea instead?
if (mBullet) { nsIFrame* outsideBullet = GetOutsideBullet();
areas.UnionAllWith(mBullet->GetRect()); if (outsideBullet) {
areas.UnionAllWith(outsideBullet->GetRect());
} }
// Factor in the bottom edge of the children. Child frames will be added // Factor in the bottom edge of the children. Child frames will be added
@ -2346,9 +2346,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
} }
// Handle an odd-ball case: a list-item with no lines // Handle an odd-ball case: a list-item with no lines
if (mBullet && HaveOutsideBullet() && mLines.empty()) { if (HasOutsideBullet() && mLines.empty()) {
nsHTMLReflowMetrics metrics; nsHTMLReflowMetrics metrics;
ReflowBullet(aState, metrics, nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, aState, metrics,
aState.mReflowState.mComputedBorderPadding.top); aState.mReflowState.mComputedBorderPadding.top);
NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0, NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0,
"empty bullet took up space"); "empty bullet took up space");
@ -2358,7 +2359,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
// we end up with *some* height. // we end up with *some* height.
if (metrics.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE && if (metrics.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE &&
!nsLayoutUtils::GetFirstLineBaseline(mBullet, &metrics.ascent)) { !nsLayoutUtils::GetFirstLineBaseline(bullet, &metrics.ascent)) {
metrics.ascent = metrics.height; metrics.ascent = metrics.height;
} }
@ -2376,7 +2377,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
nscoord offset = minAscent - metrics.ascent; nscoord offset = minAscent - metrics.ascent;
if (offset > 0) { if (offset > 0) {
mBullet->SetRect(mBullet->GetRect() + nsPoint(0, offset)); bullet->SetRect(bullet->GetRect() + nsPoint(0, offset));
} }
} }
} }
@ -2862,7 +2863,7 @@ nsBlockFrame::IsSelfEmpty()
return false; return false;
} }
if (HaveOutsideBullet() && !BulletIsEmpty()) { if (HasOutsideBullet() && !BulletIsEmpty()) {
return false; return false;
} }
@ -4188,17 +4189,18 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// first or second line. It's only placed on the second line in a // first or second line. It's only placed on the second line in a
// rare case: when the first line is empty. // rare case: when the first line is empty.
bool addedBullet = false; bool addedBullet = false;
if (mBullet && HaveOutsideBullet() && if (HasOutsideBullet() &&
((aLine == mLines.front() && ((aLine == mLines.front() &&
(!aLineLayout.IsZeroHeight() || (aLine == mLines.back()))) || (!aLineLayout.IsZeroHeight() || (aLine == mLines.back()))) ||
(mLines.front() != mLines.back() && (mLines.front() != mLines.back() &&
0 == mLines.front()->mBounds.height && 0 == mLines.front()->mBounds.height &&
aLine == mLines.begin().next()))) { aLine == mLines.begin().next()))) {
nsHTMLReflowMetrics metrics; nsHTMLReflowMetrics metrics;
ReflowBullet(aState, metrics, aState.mY); nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, aState, metrics, aState.mY);
NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0, NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0,
"empty bullet took up space"); "empty bullet took up space");
aLineLayout.AddBulletFrame(mBullet, metrics); aLineLayout.AddBulletFrame(bullet, metrics);
addedBullet = true; addedBullet = true;
} }
aLineLayout.VerticalAlignLine(); aLineLayout.VerticalAlignLine();
@ -4281,7 +4283,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
aLineLayout.RelativePositionFrames(overflowAreas); aLineLayout.RelativePositionFrames(overflowAreas);
aLine->SetOverflowAreas(overflowAreas); aLine->SetOverflowAreas(overflowAreas);
if (addedBullet) { if (addedBullet) {
aLineLayout.RemoveBulletFrame(mBullet); aLineLayout.RemoveBulletFrame(GetOutsideBullet());
} }
// Inline lines do not have margins themselves; however they are // Inline lines do not have margins themselves; however they are
@ -4670,6 +4672,43 @@ nsBlockFrame::SetOverflowOutOfFlows(const nsFrameList& aList,
} }
} }
nsBulletFrame*
nsBlockFrame::GetInsideBullet() const
{
if (!HasInsideBullet()) {
return nsnull;
}
NS_ASSERTION(!HasOutsideBullet(), "invalid bullet state");
nsBulletFrame* frame =
static_cast<nsBulletFrame*>(Properties().Get(InsideBulletProperty()));
NS_ASSERTION(frame && frame->GetType() == nsGkAtoms::bulletFrame,
"bogus inside bullet frame");
return frame;
}
nsBulletFrame*
nsBlockFrame::GetOutsideBullet() const
{
nsFrameList* list = GetOutsideBulletList();
return list ? static_cast<nsBulletFrame*>(list->FirstChild())
: nsnull;
}
nsFrameList*
nsBlockFrame::GetOutsideBulletList() const
{
if (!HasOutsideBullet()) {
return nsnull;
}
NS_ASSERTION(!HasInsideBullet(), "invalid bullet state");
nsFrameList* list =
static_cast<nsFrameList*>(Properties().Get(OutsideBulletProperty()));
NS_ASSERTION(list && list->GetLength() == 1 &&
list->FirstChild()->GetType() == nsGkAtoms::bulletFrame,
"bogus outside bullet list");
return list;
}
nsFrameList* nsFrameList*
nsBlockFrame::GetPushedFloats() const nsBlockFrame::GetPushedFloats() const
{ {
@ -4833,10 +4872,8 @@ nsBlockFrame::AddFrames(nsFrameList& aFrameList, nsIFrame* aPrevSibling)
// If we're inserting at the beginning of our list and we have an // If we're inserting at the beginning of our list and we have an
// inside bullet, insert after that bullet. // inside bullet, insert after that bullet.
if (!aPrevSibling && mBullet && !HaveOutsideBullet()) { if (!aPrevSibling && HasInsideBullet()) {
NS_ASSERTION(!aFrameList.ContainsFrame(mBullet), aPrevSibling = GetInsideBullet();
"Trying to make mBullet prev sibling to itself");
aPrevSibling = mBullet;
} }
nsIPresShell *presShell = PresContext()->PresShell(); nsIPresShell *presShell = PresContext()->PresShell();
@ -6305,9 +6342,10 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
} }
} }
if (NS_SUCCEEDED(rv) && (nsnull != mBullet) && HaveOutsideBullet()) { if (NS_SUCCEEDED(rv) && HasOutsideBullet()) {
// Display outside bullets manually // Display outside bullets manually
rv = BuildDisplayListForChild(aBuilder, mBullet, aDirtyRect, aLists); nsIFrame* bullet = GetOutsideBullet();
rv = BuildDisplayListForChild(aBuilder, bullet, aDirtyRect, aLists);
} }
#ifdef DEBUG #ifdef DEBUG
@ -6351,7 +6389,7 @@ nsBlockFrame::CreateAccessible()
presContext->PresShell()); presContext->PresShell());
} }
if (!mBullet || !presContext) { if (!HasBullet() || !presContext) {
if (!mContent->GetParent()) { if (!mContent->GetParent()) {
// Don't create accessible objects for the root content node, they are redundant with // Don't create accessible objects for the root content node, they are redundant with
// the nsDocAccessible object created with the document node // the nsDocAccessible object created with the document node
@ -6439,7 +6477,7 @@ nsBlockFrame::ChildIsDirty(nsIFrame* aChild)
if (aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW && if (aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
aChild->GetStyleDisplay()->IsAbsolutelyPositioned()) { aChild->GetStyleDisplay()->IsAbsolutelyPositioned()) {
// do nothing // do nothing
} else if (aChild == mBullet && HaveOutsideBullet()) { } else if (aChild == GetOutsideBullet()) {
// The bullet lives in the first line, unless the first line has // The bullet lives in the first line, unless the first line has
// height 0 and there is a second line, in which case it lives // height 0 and there is a second line, in which case it lives
// in the second line. // in the second line.
@ -6474,15 +6512,9 @@ nsBlockFrame::Init(nsIContent* aContent,
nsIFrame* aPrevInFlow) nsIFrame* aPrevInFlow)
{ {
if (aPrevInFlow) { if (aPrevInFlow) {
// Copy over the block frame type flags // Copy over the inherited block frame bits from the prev-in-flow.
nsBlockFrame* blockFrame = (nsBlockFrame*)aPrevInFlow; SetFlags(aPrevInFlow->GetStateBits() &
(NS_BLOCK_FLAGS_MASK & ~NS_BLOCK_FLAGS_NON_INHERITED_MASK));
// Don't copy NS_BLOCK_HAS_FIRST_LETTER_CHILD as that is set on the first
// continuation only.
SetFlags(blockFrame->mState &
(NS_BLOCK_FLAGS_MASK &
(~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET &
~NS_BLOCK_HAS_FIRST_LETTER_CHILD)));
} }
nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow); nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow);
@ -6498,6 +6530,11 @@ NS_IMETHODIMP
nsBlockFrame::SetInitialChildList(ChildListID aListID, nsBlockFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) nsFrameList& aChildList)
{ {
NS_ASSERTION(aListID != kPrincipalList ||
(GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET |
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0,
"how can we have a bullet already?");
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (kAbsoluteList == aListID) { if (kAbsoluteList == aListID) {
@ -6556,10 +6593,9 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
} }
possibleListItem = parent; possibleListItem = parent;
} }
if ((nsnull == GetPrevInFlow()) && if (NS_STYLE_DISPLAY_LIST_ITEM ==
(NS_STYLE_DISPLAY_LIST_ITEM == possibleListItem->GetStyleDisplay()->mDisplay &&
possibleListItem->GetStyleDisplay()->mDisplay) && !GetPrevInFlow()) {
(nsnull == mBullet)) {
// Resolve style for the bullet frame // Resolve style for the bullet frame
const nsStyleList* styleList = GetStyleList(); const nsStyleList* styleList = GetStyleList();
nsCSSPseudoElements::Type pseudoType; nsCSSPseudoElements::Type pseudoType;
@ -6585,7 +6621,7 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
// Create bullet frame // Create bullet frame
nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC); nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC);
if (nsnull == bullet) { if (!bullet) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
bullet->Init(mContent, this, nsnull); bullet->Init(mContent, this, nsnull);
@ -6593,16 +6629,16 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
// If the list bullet frame should be positioned inside then add // If the list bullet frame should be positioned inside then add
// it to the flow now. // it to the flow now.
if (NS_STYLE_LIST_STYLE_POSITION_INSIDE == if (NS_STYLE_LIST_STYLE_POSITION_INSIDE ==
styleList->mListStylePosition) { styleList->mListStylePosition) {
nsFrameList bulletList(bullet, bullet); nsFrameList bulletList(bullet, bullet);
AddFrames(bulletList, nsnull); AddFrames(bulletList, nsnull);
mState &= ~NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET; Properties().Set(InsideBulletProperty(), bullet);
AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
} else {
nsFrameList* bulletList = new nsFrameList(bullet, bullet);
Properties().Set(OutsideBulletProperty(), bulletList);
AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
} }
else {
mState |= NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET;
}
mBullet = bullet;
} }
} }
@ -6613,8 +6649,7 @@ bool
nsBlockFrame::BulletIsEmpty() const nsBlockFrame::BulletIsEmpty() const
{ {
NS_ASSERTION(mContent->GetPrimaryFrame()->GetStyleDisplay()->mDisplay == NS_ASSERTION(mContent->GetPrimaryFrame()->GetStyleDisplay()->mDisplay ==
NS_STYLE_DISPLAY_LIST_ITEM && NS_STYLE_DISPLAY_LIST_ITEM && HasOutsideBullet(),
HaveOutsideBullet(),
"should only care when we have an outside bullet"); "should only care when we have an outside bullet");
const nsStyleList* list = GetStyleList(); const nsStyleList* list = GetStyleList();
return list->mListStyleType == NS_STYLE_LIST_STYLE_NONE && return list->mListStyleType == NS_STYLE_LIST_STYLE_NONE &&
@ -6638,24 +6673,15 @@ nsBlockFrame::GetBulletText(nsAString& aText) const
aText.Assign(kSquareCharacter); aText.Assign(kSquareCharacter);
} }
else if (myList->mListStyleType != NS_STYLE_LIST_STYLE_NONE) { else if (myList->mListStyleType != NS_STYLE_LIST_STYLE_NONE) {
nsAutoString text; nsBulletFrame* bullet = GetBullet();
mBullet->GetListItemText(*myList, text); if (bullet) {
aText = text; nsAutoString text;
bullet->GetListItemText(*myList, text);
aText = text;
}
} }
} }
bool
nsBlockFrame::HasBullet() const
{
if (mBullet) {
const nsStyleList* styleList = GetStyleList();
return styleList->GetListStyleImage() ||
styleList->mListStyleType != NS_STYLE_LIST_STYLE_NONE;
}
return false;
}
// static // static
bool bool
nsBlockFrame::FrameStartsCounterScope(nsIFrame* aFrame) nsBlockFrame::FrameStartsCounterScope(nsIFrame* aFrame)
@ -6763,15 +6789,15 @@ nsBlockFrame::RenumberListsFor(nsPresContext* aPresContext,
// something foreign has crept in. // something foreign has crept in.
nsBlockFrame* listItem = nsLayoutUtils::GetAsBlock(kid); nsBlockFrame* listItem = nsLayoutUtils::GetAsBlock(kid);
if (listItem) { if (listItem) {
if (nsnull != listItem->mBullet) { nsBulletFrame* bullet = listItem->GetBullet();
if (bullet) {
bool changed; bool changed;
*aOrdinal = listItem->mBullet->SetListItemOrdinal(*aOrdinal, *aOrdinal = bullet->SetListItemOrdinal(*aOrdinal, &changed);
&changed);
if (changed) { if (changed) {
kidRenumberedABullet = true; kidRenumberedABullet = true;
// The ordinal changed - mark the bullet frame dirty. // The ordinal changed - mark the bullet frame dirty.
listItem->ChildIsDirty(listItem->mBullet); listItem->ChildIsDirty(bullet);
} }
} }
@ -6803,7 +6829,8 @@ nsBlockFrame::RenumberListsFor(nsPresContext* aPresContext,
} }
void void
nsBlockFrame::ReflowBullet(nsBlockReflowState& aState, nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics, nsHTMLReflowMetrics& aMetrics,
nscoord aLineTop) nscoord aLineTop)
{ {
@ -6819,10 +6846,10 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
// XXXwaterson Should this look just like the logic in // XXXwaterson Should this look just like the logic in
// nsBlockReflowContext::ReflowBlock and nsLineLayout::ReflowFrame? // nsBlockReflowContext::ReflowBlock and nsLineLayout::ReflowFrame?
nsHTMLReflowState reflowState(aState.mPresContext, rs, nsHTMLReflowState reflowState(aState.mPresContext, rs,
mBullet, availSize); aBulletFrame, availSize);
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(aState.mPresContext); aBulletFrame->WillReflow(aState.mPresContext);
mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status); aBulletFrame->Reflow(aState.mPresContext, aMetrics, reflowState, status);
// Get the float available space using our saved state from before we // Get the float available space using our saved state from before we
// started reflowing the block, so that we ignore any floats inside // started reflowing the block, so that we ignore any floats inside
@ -6862,8 +6889,9 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
// Approximate the bullets position; vertical alignment will provide // Approximate the bullets position; vertical alignment will provide
// the final vertical location. // the final vertical location.
nscoord y = aState.mContentArea.y; nscoord y = aState.mContentArea.y;
mBullet->SetRect(nsRect(x, y, aMetrics.width, aMetrics.height)); aBulletFrame->SetRect(nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(aState.mPresContext, &aState.mReflowState, NS_FRAME_REFLOW_FINISHED); aBulletFrame->DidReflow(aState.mPresContext, &aState.mReflowState,
NS_FRAME_REFLOW_FINISHED);
} }
// This is used to scan frames for any float placeholders, add their // This is used to scan frames for any float placeholders, add their

View File

@ -241,12 +241,14 @@ public:
/** /**
* Return the bullet text equivalent. * Return the bullet text equivalent.
*/ */
virtual void GetBulletText(nsAString& aText) const; void GetBulletText(nsAString& aText) const;
/** /**
* Return true if there's a bullet. * Return true if there's a bullet.
*/ */
virtual bool HasBullet() const; bool HasBullet() const {
return HasOutsideBullet() || HasInsideBullet();
}
virtual void MarkIntrinsicWidthsDirty(); virtual void MarkIntrinsicWidthsDirty();
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext); virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
@ -363,15 +365,6 @@ protected:
mState |= aFlags; mState |= aFlags;
} }
bool HaveOutsideBullet() const {
#if defined(DEBUG) && !defined(DEBUG_rods)
if(mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET) {
NS_ASSERTION(mBullet,"NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET flag set and no mBullet");
}
#endif
return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}
/** move the frames contained by aLine by aDY /** move the frames contained by aLine by aDY
* if aLine is a block, its child floats are added to the state manager * if aLine is a block, its child floats are added to the state manager
*/ */
@ -682,7 +675,8 @@ protected:
static bool FrameStartsCounterScope(nsIFrame* aFrame); static bool FrameStartsCounterScope(nsIFrame* aFrame);
void ReflowBullet(nsBlockReflowState& aState, void ReflowBullet(nsIFrame* aBulletFrame,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics, nsHTMLReflowMetrics& aMetrics,
nscoord aLineTop); nscoord aLineTop);
@ -735,6 +729,43 @@ protected:
nsFrameList* GetOverflowOutOfFlows() const; nsFrameList* GetOverflowOutOfFlows() const;
void SetOverflowOutOfFlows(const nsFrameList& aList, nsFrameList* aPropValue); void SetOverflowOutOfFlows(const nsFrameList& aList, nsFrameList* aPropValue);
/**
* @return true if this frame has an inside bullet frame.
*/
bool HasInsideBullet() const {
return 0 != (mState & NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
}
/**
* @return the inside bullet frame or nsnull if we don't have one.
*/
nsBulletFrame* GetInsideBullet() const;
/**
* @return true if this frame has an outside bullet frame.
*/
bool HasOutsideBullet() const {
return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}
/**
* @return the outside bullet frame or nsnull if we don't have one.
*/
nsBulletFrame* GetOutsideBullet() const;
/**
* @return the outside bullet frame list frame property.
*/
nsFrameList* GetOutsideBulletList() const;
/**
* @return the bullet frame or nsnull if we don't have one.
*/
nsBulletFrame* GetBullet() const {
nsBulletFrame* outside = GetOutsideBullet();
return outside ? outside : GetInsideBullet();
}
/** /**
* @return true if this frame has pushed floats. * @return true if this frame has pushed floats.
*/ */
@ -761,12 +792,9 @@ protected:
nsLineList mLines; nsLineList mLines;
// List of all floats in this block // List of all floats in this block
// XXXmats blocks rarely have floats, make it a frame property
nsFrameList mFloats; nsFrameList mFloats;
// XXX_fix_me: subclass one more time!
// For list-item frames, this is the bullet frame.
nsBulletFrame* mBullet;
friend class nsBlockReflowState; friend class nsBlockReflowState;
friend class nsBlockInFlowLineIterator; friend class nsBlockInFlowLineIterator;

View File

@ -73,6 +73,10 @@ class nsTableColFrame;
* frame among the block's descendants. If there is a floating first-letter * frame among the block's descendants. If there is a floating first-letter
* frame, or the block has first-letter style but has no first letter, this * frame, or the block has first-letter style but has no first letter, this
* bit is not set. This bit is set on the first continuation only. * bit is not set. This bit is set on the first continuation only.
*
* NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET and NS_BLOCK_FRAME_HAS_INSIDE_BULLET
* means the block has an associated bullet frame, they are mutually exclusive.
*
*/ */
#define NS_BLOCK_MARGIN_ROOT NS_FRAME_STATE_BIT(22) #define NS_BLOCK_MARGIN_ROOT NS_FRAME_STATE_BIT(22)
#define NS_BLOCK_FLOAT_MGR NS_FRAME_STATE_BIT(23) #define NS_BLOCK_FLOAT_MGR NS_FRAME_STATE_BIT(23)
@ -80,14 +84,25 @@ class nsTableColFrame;
#define NS_BLOCK_HAS_FIRST_LETTER_STYLE NS_FRAME_STATE_BIT(29) #define NS_BLOCK_HAS_FIRST_LETTER_STYLE NS_FRAME_STATE_BIT(29)
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET NS_FRAME_STATE_BIT(30) #define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET NS_FRAME_STATE_BIT(30)
#define NS_BLOCK_HAS_FIRST_LETTER_CHILD NS_FRAME_STATE_BIT(31) #define NS_BLOCK_HAS_FIRST_LETTER_CHILD NS_FRAME_STATE_BIT(31)
// These are the bits that get inherited from a block frame to its #define NS_BLOCK_FRAME_HAS_INSIDE_BULLET NS_FRAME_STATE_BIT(63)
// next-in-flows and are not private to blocks // These are all the block specific frame bits, they are copied from
#define NS_BLOCK_FLAGS_MASK (NS_BLOCK_MARGIN_ROOT | \ // the prev-in-flow to a newly created next-in-flow, except for the
NS_BLOCK_FLOAT_MGR | \ // NS_BLOCK_FLAGS_NON_INHERITED_MASK bits below.
NS_BLOCK_CLIP_PAGINATED_OVERFLOW | \ #define NS_BLOCK_FLAGS_MASK (NS_BLOCK_MARGIN_ROOT | \
NS_BLOCK_HAS_FIRST_LETTER_STYLE | \ NS_BLOCK_FLOAT_MGR | \
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \ NS_BLOCK_CLIP_PAGINATED_OVERFLOW | \
NS_BLOCK_HAS_FIRST_LETTER_CHILD) NS_BLOCK_HAS_FIRST_LETTER_STYLE | \
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \
NS_BLOCK_HAS_FIRST_LETTER_CHILD | \
NS_BLOCK_FRAME_HAS_INSIDE_BULLET)
// This is the subset of NS_BLOCK_FLAGS_MASK that is NOT inherited
// by default. They should only be set on the first-in-flow.
// See nsBlockFrame::Init.
#define NS_BLOCK_FLAGS_NON_INHERITED_MASK \
(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \
NS_BLOCK_HAS_FIRST_LETTER_CHILD | \
NS_BLOCK_FRAME_HAS_INSIDE_BULLET)
// Factory methods for creating html layout objects // Factory methods for creating html layout objects