mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 18:47:53 +00:00
Bug 838688 - Make ReparentFloats/CollectFloats not require a priori knowledge of which child list a float is expected to be on. r=bzbarsky
This commit is contained in:
parent
8b24a5ee5f
commit
68ac87f2e4
@ -1792,11 +1792,10 @@ static bool LineHasClear(nsLineBox* aLine) {
|
|||||||
* removed from the list. They end up appended to our mFloats list.
|
* removed from the list. They end up appended to our mFloats list.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame,
|
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
|
||||||
nsBlockFrame* aOldParent, bool aFromOverflow,
|
|
||||||
bool aReparentSiblings) {
|
bool aReparentSiblings) {
|
||||||
nsFrameList list;
|
nsFrameList list;
|
||||||
aOldParent->CollectFloats(aFirstFrame, list, aFromOverflow, aReparentSiblings);
|
aOldParent->CollectFloats(aFirstFrame, list, aReparentSiblings);
|
||||||
if (list.NotEmpty()) {
|
if (list.NotEmpty()) {
|
||||||
for (nsIFrame* f = list.FirstChild(); f; f = f->GetNextSibling()) {
|
for (nsIFrame* f = list.FirstChild(); f; f = f->GetNextSibling()) {
|
||||||
ReparentFrame(f, aOldParent, this);
|
ReparentFrame(f, aOldParent, this);
|
||||||
@ -2247,7 +2246,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
nsBlockFrame* nextInFlow = aState.mNextInFlow;
|
nsBlockFrame* nextInFlow = aState.mNextInFlow;
|
||||||
nsLineBox* pulledLine;
|
nsLineBox* pulledLine;
|
||||||
nsFrameList pulledFrames;
|
nsFrameList pulledFrames;
|
||||||
bool isOverflowLine = false;
|
|
||||||
if (!nextInFlow->mLines.empty()) {
|
if (!nextInFlow->mLines.empty()) {
|
||||||
RemoveFirstLine(nextInFlow->mLines, nextInFlow->mFrames,
|
RemoveFirstLine(nextInFlow->mLines, nextInFlow->mFrames,
|
||||||
&pulledLine, &pulledFrames);
|
&pulledLine, &pulledFrames);
|
||||||
@ -2265,7 +2263,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (last) {
|
if (last) {
|
||||||
nextInFlow->DestroyOverflowLines();
|
nextInFlow->DestroyOverflowLines();
|
||||||
}
|
}
|
||||||
isOverflowLine = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pulledFrames.IsEmpty()) {
|
if (pulledFrames.IsEmpty()) {
|
||||||
@ -2295,7 +2292,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mPrevChild = mFrames.LastChild();
|
aState.mPrevChild = mFrames.LastChild();
|
||||||
|
|
||||||
// Reparent floats whose placeholders are in the line.
|
// Reparent floats whose placeholders are in the line.
|
||||||
ReparentFloats(pulledLine->mFirstChild, nextInFlow, isOverflowLine, true);
|
ReparentFloats(pulledLine->mFirstChild, nextInFlow, true);
|
||||||
|
|
||||||
DumpLine(aState, pulledLine, deltaY, 0);
|
DumpLine(aState, pulledLine, deltaY, 0);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -2595,7 +2592,7 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
|||||||
|
|
||||||
// The frame might have (or contain) floats that need to be
|
// The frame might have (or contain) floats that need to be
|
||||||
// brought over too.
|
// brought over too.
|
||||||
ReparentFloats(frame, aFromContainer, aFromOverflowLine, true);
|
ReparentFloats(frame, aFromContainer, true);
|
||||||
}
|
}
|
||||||
// when aFromContainer is 'this', then aLine->LastChild()'s next sibling
|
// when aFromContainer is 'this', then aLine->LastChild()'s next sibling
|
||||||
// is already set correctly.
|
// is already set correctly.
|
||||||
@ -4317,7 +4314,7 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||||||
if (overBegin != end_lines()) {
|
if (overBegin != end_lines()) {
|
||||||
// Remove floats in the lines from mFloats
|
// Remove floats in the lines from mFloats
|
||||||
nsFrameList floats;
|
nsFrameList floats;
|
||||||
CollectFloats(overBegin->mFirstChild, floats, false, true);
|
CollectFloats(overBegin->mFirstChild, floats, true);
|
||||||
|
|
||||||
if (floats.NotEmpty()) {
|
if (floats.NotEmpty()) {
|
||||||
// Push the floats onto the front of the overflow out-of-flows list
|
// Push the floats onto the front of the overflow out-of-flows list
|
||||||
@ -6899,7 +6896,7 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
|
|||||||
// are ignored (they are not added to aList).
|
// are ignored (they are not added to aList).
|
||||||
void
|
void
|
||||||
nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
||||||
bool aFromOverflow, bool aCollectSiblings)
|
bool aCollectSiblings)
|
||||||
{
|
{
|
||||||
while (aFrame) {
|
while (aFrame) {
|
||||||
// Don't descend into float containing blocks.
|
// Don't descend into float containing blocks.
|
||||||
@ -6908,19 +6905,28 @@ nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
|||||||
aFrame->GetType() == nsGkAtoms::placeholderFrame ?
|
aFrame->GetType() == nsGkAtoms::placeholderFrame ?
|
||||||
nsLayoutUtils::GetFloatFromPlaceholder(aFrame) : nullptr;
|
nsLayoutUtils::GetFloatFromPlaceholder(aFrame) : nullptr;
|
||||||
if (outOfFlowFrame && outOfFlowFrame->GetParent() == this) {
|
if (outOfFlowFrame && outOfFlowFrame->GetParent() == this) {
|
||||||
bool removed = false;
|
// Floats live in mFloats, or in the PushedFloat or OverflowOutOfFlows
|
||||||
if (outOfFlowFrame->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT) {
|
// frame list properties.
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!mFloats.ContainsFrame(outOfFlowFrame)) {
|
||||||
nsFrameList* list = GetPushedFloats();
|
nsFrameList* list = GetPushedFloats();
|
||||||
removed = list && list->RemoveFrameIfPresent(outOfFlowFrame);
|
if (!list || !list->ContainsFrame(outOfFlowFrame)) {
|
||||||
}
|
list = GetOverflowOutOfFlows();
|
||||||
if (!removed) {
|
MOZ_ASSERT(list && list->ContainsFrame(outOfFlowFrame),
|
||||||
if (aFromOverflow) {
|
"the float is not our child");
|
||||||
nsAutoOOFFrameList oofs(this);
|
|
||||||
oofs.mList.RemoveFrame(outOfFlowFrame);
|
|
||||||
} else {
|
|
||||||
mFloats.RemoveFrame(outOfFlowFrame);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
bool removed = mFloats.StartRemoveFrame(outOfFlowFrame);
|
||||||
|
if (!removed) {
|
||||||
|
nsFrameList* list = GetPushedFloats();
|
||||||
|
removed = list && list->ContinueRemoveFrame(outOfFlowFrame);
|
||||||
|
if (!removed) {
|
||||||
|
nsAutoOOFFrameList oofs(this);
|
||||||
|
removed = oofs.mList.ContinueRemoveFrame(outOfFlowFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(removed, "misplaced float child");
|
||||||
aList.AppendFrame(nullptr, outOfFlowFrame);
|
aList.AppendFrame(nullptr, outOfFlowFrame);
|
||||||
// FIXME: By not pulling floats whose parent is one of our
|
// FIXME: By not pulling floats whose parent is one of our
|
||||||
// later siblings, are we risking the pushed floats getting
|
// later siblings, are we risking the pushed floats getting
|
||||||
@ -6928,13 +6934,8 @@ nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
|||||||
// XXXmats nsInlineFrame's lazy reparenting depends on NOT doing that.
|
// XXXmats nsInlineFrame's lazy reparenting depends on NOT doing that.
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectFloats(aFrame->GetFirstPrincipalChild(),
|
CollectFloats(aFrame->GetFirstPrincipalChild(), aList, true);
|
||||||
aList, aFromOverflow, true);
|
CollectFloats(aFrame->GetFirstChild(kOverflowList), aList, true);
|
||||||
// Note: Even though we're calling CollectFloats on aFrame's overflow
|
|
||||||
// list, we'll pass down aFromOverflow unchanged because we're still
|
|
||||||
// traversing the regular-children subtree of the 'this' frame.
|
|
||||||
CollectFloats(aFrame->GetFirstChild(kOverflowList),
|
|
||||||
aList, aFromOverflow, true);
|
|
||||||
}
|
}
|
||||||
if (!aCollectSiblings)
|
if (!aCollectSiblings)
|
||||||
break;
|
break;
|
||||||
|
@ -457,8 +457,7 @@ public:
|
|||||||
};
|
};
|
||||||
nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags);
|
nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags);
|
||||||
|
|
||||||
void ReparentFloats(nsIFrame* aFirstFrame,
|
void ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
|
||||||
nsBlockFrame* aOldParent, bool aFromOverflow,
|
|
||||||
bool aReparentSiblings);
|
bool aReparentSiblings);
|
||||||
|
|
||||||
virtual bool UpdateOverflow();
|
virtual bool UpdateOverflow();
|
||||||
@ -506,7 +505,7 @@ protected:
|
|||||||
void RemoveFloat(nsIFrame* aFloat);
|
void RemoveFloat(nsIFrame* aFloat);
|
||||||
|
|
||||||
void CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
void CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
|
||||||
bool aFromOverflow, bool aCollectFromSiblings);
|
bool aCollectFromSiblings);
|
||||||
// Remove a float, abs, rel positioned frame from the appropriate block's list
|
// Remove a float, abs, rel positioned frame from the appropriate block's list
|
||||||
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
|
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
@ -243,9 +243,7 @@ nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* ancestor = aFrame;
|
nsIFrame* ancestor = aFrame;
|
||||||
nsIFrame* ancestorBlockChild;
|
|
||||||
do {
|
do {
|
||||||
ancestorBlockChild = ancestor;
|
|
||||||
ancestor = ancestor->GetParent();
|
ancestor = ancestor->GetParent();
|
||||||
if (!ancestor)
|
if (!ancestor)
|
||||||
return;
|
return;
|
||||||
@ -259,11 +257,8 @@ nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
|||||||
nsBlockFrame* frameBlock = nsLayoutUtils::GetAsBlock(ancestor);
|
nsBlockFrame* frameBlock = nsLayoutUtils::GetAsBlock(ancestor);
|
||||||
NS_ASSERTION(frameBlock, "ancestor not a block");
|
NS_ASSERTION(frameBlock, "ancestor not a block");
|
||||||
|
|
||||||
const nsFrameList& blockChildren(ancestor->PrincipalChildList());
|
|
||||||
bool isOverflow = !blockChildren.ContainsFrame(ancestorBlockChild);
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ourBlock->ReparentFloats(aFrame, frameBlock, isOverflow, false);
|
ourBlock->ReparentFloats(aFrame, frameBlock, false);
|
||||||
|
|
||||||
if (!aReparentSiblings)
|
if (!aReparentSiblings)
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user