Bug 501847 part 1. Some preparatory cleanup of GetIBSpecialSiblingForAnonymousBlock. r=roc

This commit is contained in:
Boris Zbarsky 2009-09-18 14:00:20 -04:00
Родитель adf60cf031
Коммит 28b855a104
4 изменённых файлов: 47 добавлений и 89 удалений

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

@ -465,20 +465,19 @@ IsFrameSpecial(nsIFrame* aFrame)
static nsIFrame* GetSpecialSibling(nsIFrame* aFrame) static nsIFrame* GetSpecialSibling(nsIFrame* aFrame)
{ {
NS_PRECONDITION(IsFrameSpecial(aFrame), "Shouldn't call this");
// We only store the "special sibling" annotation with the first // We only store the "special sibling" annotation with the first
// frame in the continuation chain. Walk back to find that frame now. // frame in the continuation chain. Walk back to find that frame now.
aFrame = aFrame->GetFirstContinuation(); return
static_cast<nsIFrame*>
void* value = aFrame->GetProperty(nsGkAtoms::IBSplitSpecialSibling); (aFrame->GetFirstContinuation()->
GetProperty(nsGkAtoms::IBSplitSpecialSibling));
return static_cast<nsIFrame*>(value);
} }
static nsIFrame* static nsIFrame* GetSpecialPrevSibling(nsIFrame* aFrame)
GetIBSplitSpecialPrevSiblingForAnonymousBlock(nsIFrame* aFrame)
{ {
NS_PRECONDITION(IsFrameSpecial(aFrame) && !IsInlineFrame(aFrame), NS_PRECONDITION(IsFrameSpecial(aFrame), "Shouldn't call this");
"Shouldn't call this");
// We only store the "special sibling" annotation with the first // We only store the "special sibling" annotation with the first
// frame in the continuation chain. Walk back to find that frame now. // frame in the continuation chain. Walk back to find that frame now.
@ -506,19 +505,24 @@ SetFrameIsSpecial(nsIFrame* aFrame, nsIFrame* aSpecialSibling)
{ {
NS_PRECONDITION(aFrame, "bad args!"); NS_PRECONDITION(aFrame, "bad args!");
// Mark the frame and all of its siblings as "special". // We should be the only continuation
for (nsIFrame* frame = aFrame; frame != nsnull; frame = frame->GetNextContinuation()) { NS_ASSERTION(!aFrame->GetPrevContinuation(),
frame->AddStateBits(NS_FRAME_IS_SPECIAL); "assigning special sibling to other than first continuation!");
} NS_ASSERTION(!aFrame->GetNextContinuation(),
"should have no continuations here");
// Mark the frame as "special".
aFrame->AddStateBits(NS_FRAME_IS_SPECIAL);
if (aSpecialSibling) { if (aSpecialSibling) {
// We should be the first continuation NS_ASSERTION(!aSpecialSibling->GetPrevContinuation(),
NS_ASSERTION(!aFrame->GetPrevContinuation(), "assigning something other than the first continuation as the "
"assigning special sibling to other than first continuation!"); "special sibling");
// Store the "special sibling" (if we were given one) with the // Store the "special sibling" (if we were given one) with the
// first frame in the flow. // first frame in the flow.
aFrame->SetProperty(nsGkAtoms::IBSplitSpecialSibling, aSpecialSibling); aFrame->SetProperty(nsGkAtoms::IBSplitSpecialSibling, aSpecialSibling);
aSpecialSibling->SetProperty(nsGkAtoms::IBSplitSpecialPrevSibling, aFrame);
} }
} }
@ -596,21 +600,6 @@ FindLastBlock(const nsFrameList& aList)
return last; return last;
} }
/*
* The special-prev-sibling is useful for
* finding the "special parent" of a frame (i.e., a frame from which a
* good parent style context can be obtained), one looks at the
* special previous sibling annotation of the real parent of the frame
* (if the real parent has NS_FRAME_IS_SPECIAL).
*/
inline void
MarkIBSpecialPrevSibling(nsIFrame *aAnonymousFrame,
nsIFrame *aSpecialParent)
{
aAnonymousFrame->SetProperty(nsGkAtoms::IBSplitSpecialPrevSibling,
aSpecialParent, nsnull, nsnull);
}
inline void inline void
SetInitialSingleChild(nsIFrame* aParent, nsIFrame* aFrame) SetInitialSingleChild(nsIFrame* aParent, nsIFrame* aFrame)
{ {
@ -10809,8 +10798,6 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
SetFrameIsSpecial(newFrame, blockFrame); SetFrameIsSpecial(newFrame, blockFrame);
SetFrameIsSpecial(blockFrame, inlineFrame); SetFrameIsSpecial(blockFrame, inlineFrame);
SetFrameIsSpecial(inlineFrame, nsnull); SetFrameIsSpecial(inlineFrame, nsnull);
MarkIBSpecialPrevSibling(blockFrame, newFrame);
MarkIBSpecialPrevSibling(inlineFrame, blockFrame);
#ifdef DEBUG #ifdef DEBUG
if (gNoisyInlineConstruction) { if (gNoisyInlineConstruction) {
@ -11154,8 +11141,8 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
// here is to construct with the right parents to start with. // here is to construct with the right parents to start with.
nsIFrame* floatContainer = aFrame; nsIFrame* floatContainer = aFrame;
do { do {
floatContainer = GetFloatContainingBlock( floatContainer =
GetIBSplitSpecialPrevSiblingForAnonymousBlock(floatContainer)); GetFloatContainingBlock(GetSpecialPrevSibling(floatContainer));
if (!floatContainer) { if (!floatContainer) {
break; break;
} }

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

@ -270,7 +270,8 @@ protected:
(aFrame->GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling)); (aFrame->GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling));
if (block) { if (block) {
// The {ib} properties are only stored on first continuations // The {ib} properties are only stored on first continuations
block = block->GetFirstContinuation(); NS_ASSERTION(!block->GetPrevContinuation(),
"Incorrect value for IBSplitSpecialPrevSibling");
prevCont = prevCont =
static_cast<nsIFrame*> static_cast<nsIFrame*>
(block->GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling)); (block->GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling));

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

@ -1101,7 +1101,7 @@ nsFrameManager::ReParentStyleContext(nsIFrame* aFrame)
// reparent the same frame twice because the "if (newContext != // reparent the same frame twice because the "if (newContext !=
// oldContext)" check will prevent us from redoing work. // oldContext)" check will prevent us from redoing work.
if ((aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) && if ((aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
!aFrame->GetPrevInFlow()) { !aFrame->GetPrevContinuation()) {
nsIFrame* sib = static_cast<nsIFrame*>(aFrame->GetProperty(nsGkAtoms::IBSplitSpecialSibling)); nsIFrame* sib = static_cast<nsIFrame*>(aFrame->GetProperty(nsGkAtoms::IBSplitSpecialSibling));
if (sib) { if (sib) {
ReParentStyleContext(sib); ReParentStyleContext(sib);

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

@ -5679,17 +5679,15 @@ nsFrame::GetParentStyleContextFrame(nsPresContext* aPresContext,
/** /**
* This function takes a "special" frame and _if_ that frame is the * This function takes a "special" frame and _if_ that frame is an anonymous
* anonymous block crated by an ib split it returns the split inline * block created by an ib split it returns the block's preceding inline. This
* as aSpecialSibling. This is needed because the split inline's * is needed because the split inline's style context is the parent of the
* style context is the parent of the anonymous block's srtyle context. * anonymous block's style context.
* *
* If aFrame is not the anonymous block, aSpecialSibling is set to null. * If aFrame is not ananonymous block, null is returned.
*/ */
static nsresult static nsIFrame*
GetIBSpecialSiblingForAnonymousBlock(nsPresContext* aPresContext, GetIBSpecialSiblingForAnonymousBlock(nsIFrame* aFrame)
nsIFrame* aFrame,
nsIFrame** aSpecialSibling)
{ {
NS_PRECONDITION(aFrame, "Must have a non-null frame!"); NS_PRECONDITION(aFrame, "Must have a non-null frame!");
NS_ASSERTION(aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL, NS_ASSERTION(aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL,
@ -5698,34 +5696,22 @@ GetIBSpecialSiblingForAnonymousBlock(nsPresContext* aPresContext,
nsIAtom* type = aFrame->GetStyleContext()->GetPseudo(); nsIAtom* type = aFrame->GetStyleContext()->GetPseudo();
if (type != nsCSSAnonBoxes::mozAnonymousBlock && if (type != nsCSSAnonBoxes::mozAnonymousBlock &&
type != nsCSSAnonBoxes::mozAnonymousPositionedBlock) { type != nsCSSAnonBoxes::mozAnonymousPositionedBlock) {
// it's not the anonymous block // it's not an anonymous block
*aSpecialSibling = nsnull; return nsnull;
return NS_OK;
} }
// Find the first-in-flow of the frame. (Ugh. This ends up // Find the first continuation of the frame. (Ugh. This ends up
// being O(N^2) when it is called O(N) times.) // being O(N^2) when it is called O(N) times.)
aFrame = aFrame->GetFirstInFlow(); aFrame = aFrame->GetFirstContinuation();
/* /*
* Now look up the nsGkAtoms::IBSplitSpecialPrevSibling * Now look up the nsGkAtoms::IBSplitSpecialPrevSibling
* property, which is only set on the anonymous block frames we're * property.
* interested in.
*/ */
nsresult rv; nsIFrame *specialSibling =
nsIFrame *specialSibling = static_cast<nsIFrame*> static_cast<nsIFrame*>(aFrame->GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling));
(aPresContext->PropertyTable()->GetProperty(aFrame, NS_ASSERTION(specialSibling, "Broken frame tree?");
nsGkAtoms::IBSplitSpecialPrevSibling, &rv)); return specialSibling;
if (NS_PROPTABLE_PROP_NOT_THERE == rv) {
*aSpecialSibling = nsnull;
rv = NS_OK;
} else if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(specialSibling, "null special sibling");
*aSpecialSibling = specialSibling;
}
return rv;
} }
/** /**
@ -5784,19 +5770,10 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
nsIFrame* parent = aProspectiveParent; nsIFrame* parent = aProspectiveParent;
do { do {
if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) { if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) {
nsIFrame* sibling; nsIFrame* sibling = GetIBSpecialSiblingForAnonymousBlock(parent);
nsresult rv =
GetIBSpecialSiblingForAnonymousBlock(parent->PresContext(), parent, &sibling);
if (NS_FAILED(rv)) {
// If GetIBSpecialSiblingForAnonymousBlock fails, then what?
// we used to return what is now |aProspectiveParent|, but maybe
// |parent| would make more sense?
NS_NOTREACHED("Shouldn't get here");
return aProspectiveParent;
}
if (sibling) { if (sibling) {
// |parent| was the block in an {ib} split; use the inline as // |parent| was a block in an {ib} split; use the inline as
// |the style parent. // |the style parent.
parent = sibling; parent = sibling;
} }
@ -5846,19 +5823,12 @@ nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext,
if (!(mState & NS_FRAME_OUT_OF_FLOW)) { if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
/* /*
* If this frame is the anonymous block created when an inline * If this frame is an anonymous block created when an inline with a block
* with a block inside it got split, then the parent style context * inside it got split, then the parent style context is on its preceding
* is on the first of the three special frames. We can get to it * inline. We can get to it using GetIBSpecialSiblingForAnonymousBlock.
* using GetIBSpecialSiblingForAnonymousBlock
*/ */
if (mState & NS_FRAME_IS_SPECIAL) { if (mState & NS_FRAME_IS_SPECIAL) {
nsresult rv = *aProviderFrame = GetIBSpecialSiblingForAnonymousBlock(this);
GetIBSpecialSiblingForAnonymousBlock(aPresContext, this, aProviderFrame);
if (NS_FAILED(rv)) {
NS_NOTREACHED("Shouldn't get here");
*aProviderFrame = nsnull;
return rv;
}
if (*aProviderFrame) { if (*aProviderFrame) {
return NS_OK; return NS_OK;