зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1459937) for failing crashtest with Assertion failure: (IndexInFlow(aOldParent) < IndexInFlow(aNewParent)) on a CLOSED TREE
Backed out changeset 2cff5c67d000 (bug 1459937) Backed out changeset fb3fba19e615 (bug 1459937) Backed out changeset bd4bd8ac335c (bug 1459937)
This commit is contained in:
Родитель
846c1a6377
Коммит
10d4df5aa9
|
@ -134,11 +134,6 @@ enum class DrawStringFlags {
|
|||
};
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags)
|
||||
|
||||
enum class ReparentingDirection {
|
||||
Backwards,
|
||||
Forwards
|
||||
};
|
||||
|
||||
/**
|
||||
* nsLayoutUtils is a namespace class used for various helper
|
||||
* functions that are useful in multiple places in layout. The goal
|
||||
|
|
|
@ -606,75 +606,25 @@ nsBlockFrame::IsFloatContainingBlock() const
|
|||
}
|
||||
|
||||
static void
|
||||
ReparentFrameInternal(nsIFrame* aFrame, nsContainerFrame* aOldParent,
|
||||
nsContainerFrame* aNewParent, bool aMarkDirty)
|
||||
ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent,
|
||||
nsContainerFrame* aNewParent)
|
||||
{
|
||||
NS_ASSERTION(aOldParent == aFrame->GetParent(),
|
||||
"Parent not consistent with expectations");
|
||||
|
||||
aFrame->SetParent(aNewParent);
|
||||
if (aMarkDirty) {
|
||||
aFrame->AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsContainerFrame::ReparentFrameView(aFrame, aOldParent, aNewParent);
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldMarkReparentedFramesDirty(
|
||||
#ifdef DEBUG
|
||||
nsContainerFrame* aOldParent,
|
||||
#endif
|
||||
nsIFrame* aNewParent,
|
||||
ReparentingDirection aDirection)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(aOldParent->FirstInFlow() == aNewParent->FirstInFlow(),
|
||||
"Reparenting should be between continuations of the same frame");
|
||||
if (aOldParent->FirstInFlow() == aNewParent->FirstInFlow()) {
|
||||
auto IndexInFlow =
|
||||
[](const nsIFrame* f) {
|
||||
int i = 0; while ((f = f->GetPrevInFlow())) { ++i; } return i;
|
||||
};
|
||||
MOZ_ASSERT((IndexInFlow(aOldParent) < IndexInFlow(aNewParent)) ==
|
||||
(aDirection == ReparentingDirection::Forwards),
|
||||
"Parents not in expected order");
|
||||
}
|
||||
#endif
|
||||
return (aDirection == ReparentingDirection::Backwards) &&
|
||||
(aNewParent->GetStateBits() & NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
// Because a frame with NS_FRAME_IS_DIRTY marks all of its children dirty at
|
||||
// the start of its reflow, when we move a frame from a later frame backwards to
|
||||
// an earlier frame, and the earlier frame has NS_FRAME_IS_DIRTY (though that
|
||||
// should corresponded with the later frame having NS_FRAME_IS_DIRTY), we need
|
||||
// to add NS_FRAME_IS_DIRTY to the reparented frame.
|
||||
static void
|
||||
ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent,
|
||||
nsContainerFrame* aNewParent, ReparentingDirection aDirection)
|
||||
{
|
||||
const bool markDirty = ShouldMarkReparentedFramesDirty(
|
||||
#ifdef DEBUG
|
||||
aOldParent,
|
||||
#endif
|
||||
aNewParent, aDirection);
|
||||
ReparentFrameInternal(aFrame, aOldParent, aNewParent, markDirty);
|
||||
}
|
||||
|
||||
static void
|
||||
ReparentFrames(nsFrameList& aFrameList, nsContainerFrame* aOldParent,
|
||||
nsContainerFrame* aNewParent, ReparentingDirection aDirection)
|
||||
nsContainerFrame* aNewParent)
|
||||
{
|
||||
const bool markDirty = ShouldMarkReparentedFramesDirty(
|
||||
#ifdef DEBUG
|
||||
aOldParent,
|
||||
#endif
|
||||
aNewParent, aDirection);
|
||||
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
|
||||
ReparentFrameInternal(e.get(), aOldParent, aNewParent, markDirty);
|
||||
ReparentFrame(e.get(), aOldParent, aNewParent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2174,16 +2124,14 @@ static bool LineHasClear(nsLineBox* aLine) {
|
|||
*/
|
||||
void
|
||||
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
|
||||
bool aReparentSiblings,
|
||||
ReparentingDirection aDirection)
|
||||
{
|
||||
bool aReparentSiblings) {
|
||||
nsFrameList list;
|
||||
aOldParent->CollectFloats(aFirstFrame, list, aReparentSiblings);
|
||||
if (list.NotEmpty()) {
|
||||
for (nsIFrame* f : list) {
|
||||
MOZ_ASSERT(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
|
||||
"CollectFloats should've removed that bit");
|
||||
ReparentFrame(f, aOldParent, this, aDirection);
|
||||
ReparentFrame(f, aOldParent, this);
|
||||
}
|
||||
mFloats.AppendFrames(nullptr, list);
|
||||
}
|
||||
|
@ -2680,8 +2628,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState)
|
|||
if (pulledLine == nextInFlow->GetLineCursor()) {
|
||||
nextInFlow->ClearLineCursor();
|
||||
}
|
||||
ReparentFrames(pulledFrames, nextInFlow, this,
|
||||
ReparentingDirection::Backwards);
|
||||
ReparentFrames(pulledFrames, nextInFlow, this);
|
||||
|
||||
NS_ASSERTION(pulledFrames.LastChild() == pulledLine->LastChild(),
|
||||
"Unexpected last frame");
|
||||
|
@ -2697,8 +2644,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState)
|
|||
aState.mPrevChild = mFrames.LastChild();
|
||||
|
||||
// Reparent floats whose placeholders are in the line.
|
||||
ReparentFloats(pulledLine->mFirstChild, nextInFlow, true,
|
||||
ReparentingDirection::Backwards);
|
||||
ReparentFloats(pulledLine->mFirstChild, nextInFlow, true);
|
||||
|
||||
DumpLine(aState, pulledLine, deltaBCoord, 0);
|
||||
#ifdef DEBUG
|
||||
|
@ -2977,13 +2923,12 @@ nsBlockFrame::PullFrameFrom(nsLineBox* aLine,
|
|||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented.
|
||||
ReparentFrame(frame, aFromContainer, this, ReparentingDirection::Backwards);
|
||||
ReparentFrame(frame, aFromContainer, this);
|
||||
mFrames.AppendFrame(nullptr, frame);
|
||||
|
||||
// The frame might have (or contain) floats that need to be brought
|
||||
// over too. (pass 'false' since there are no siblings to check)
|
||||
ReparentFloats(frame, aFromContainer, false,
|
||||
ReparentingDirection::Backwards);
|
||||
ReparentFloats(frame, aFromContainer, false);
|
||||
} else {
|
||||
MOZ_ASSERT(aLine == aFromLine.prev());
|
||||
}
|
||||
|
@ -3728,10 +3673,8 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
|
|||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
if (parent != this) {
|
||||
ReparentFrame(nextFrame, parent, this,
|
||||
ReparentingDirection::Backwards);
|
||||
}
|
||||
if (parent != this)
|
||||
ReparentFrame(nextFrame, parent, this);
|
||||
mFrames.InsertFrame(nullptr, frame, nextFrame);
|
||||
madeContinuation = true; // needs to be added to mLines
|
||||
nextFrame->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
||||
|
@ -4390,7 +4333,7 @@ nsBlockFrame::SplitFloat(BlockReflowInput& aState,
|
|||
DebugOnly<nsresult> rv = oldParent->StealFrame(nextInFlow);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame failed");
|
||||
if (oldParent != this) {
|
||||
ReparentFrame(nextInFlow, oldParent, this, ReparentingDirection::Backwards);
|
||||
ReparentFrame(nextInFlow, oldParent, this);
|
||||
}
|
||||
if (!aFloatStatus.IsOverflowIncomplete()) {
|
||||
nextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
||||
|
@ -4910,8 +4853,7 @@ nsBlockFrame::DrainOverflowLines()
|
|||
FrameLines* overflowLines = prevBlock->RemoveOverflowLines();
|
||||
if (overflowLines) {
|
||||
// Make all the frames on the overflow line list mine.
|
||||
ReparentFrames(overflowLines->mFrames, prevBlock, this,
|
||||
ReparentingDirection::Forwards);
|
||||
ReparentFrames(overflowLines->mFrames, prevBlock, this);
|
||||
|
||||
// Make the overflow out-of-flow frames mine too.
|
||||
nsAutoOOFFrameList oofs(prevBlock);
|
||||
|
@ -4925,8 +4867,7 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nif->RemoveStateBits(NS_FRAME_IS_PUSHED_FLOAT);
|
||||
}
|
||||
}
|
||||
ReparentFrames(oofs.mList, prevBlock, this,
|
||||
ReparentingDirection::Forwards);
|
||||
ReparentFrames(oofs.mList, prevBlock, this);
|
||||
mFloats.InsertFrames(nullptr, nullptr, oofs.mList);
|
||||
}
|
||||
|
||||
|
|
|
@ -540,7 +540,7 @@ public:
|
|||
}
|
||||
|
||||
void ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
|
||||
bool aReparentSiblings, ReparentingDirection aDirection);
|
||||
bool aReparentSiblings);
|
||||
|
||||
virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
|
||||
|
||||
|
|
|
@ -1595,8 +1595,7 @@ nsContainerFrame::MoveInlineOverflowToChildList(nsIFrame* aLineContainer)
|
|||
// container if the container has prev continuation.
|
||||
if (aLineContainer->GetPrevContinuation()) {
|
||||
ReparentFloatsForInlineChild(aLineContainer,
|
||||
prevOverflowFrames->FirstChild(), true,
|
||||
ReparentingDirection::Forwards);
|
||||
prevOverflowFrames->FirstChild(), true);
|
||||
}
|
||||
// When pushing and pulling frames we need to check for whether
|
||||
// any views need to be reparented.
|
||||
|
@ -1749,8 +1748,7 @@ nsContainerFrame::PullNextInFlowChild(ContinuationTraversingState& aState)
|
|||
/* static */ void
|
||||
nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
||||
nsIFrame* aFrame,
|
||||
bool aReparentSiblings,
|
||||
ReparentingDirection aDirection)
|
||||
bool aReparentSiblings)
|
||||
{
|
||||
// XXXbz this would be better if it took a nsFrameList or a frame
|
||||
// list slice....
|
||||
|
@ -1771,7 +1769,7 @@ nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
|||
NS_ASSERTION(ourBlock, "Not a block, but broke vertically?");
|
||||
|
||||
while (true) {
|
||||
ourBlock->ReparentFloats(aFrame, frameBlock, false, aDirection);
|
||||
ourBlock->ReparentFloats(aFrame, frameBlock, false);
|
||||
|
||||
if (!aReparentSiblings)
|
||||
return;
|
||||
|
@ -1786,8 +1784,7 @@ nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
|||
// trust that the frames in the sibling chain all have the same parent,
|
||||
// because lazy reparenting may be going on. If we find a different
|
||||
// parent we need to redo our analysis.
|
||||
ReparentFloatsForInlineChild(aOurLineContainer, next, aReparentSiblings,
|
||||
aDirection);
|
||||
ReparentFloatsForInlineChild(aOurLineContainer, next, aReparentSiblings);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -674,8 +674,7 @@ protected:
|
|||
*/
|
||||
static void ReparentFloatsForInlineChild(nsIFrame* aOurBlock,
|
||||
nsIFrame* aFrame,
|
||||
bool aReparentSiblings,
|
||||
ReparentingDirection aDirection);
|
||||
bool aReparentSiblings);
|
||||
|
||||
// ==========================================================================
|
||||
/*
|
||||
|
|
|
@ -806,8 +806,7 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
|
|||
// The blockChildren.ContainsFrame check performed by
|
||||
// ReparentFloatsForInlineChild will be fast because frame's ancestor
|
||||
// will be the first child of its containing block.
|
||||
ReparentFloatsForInlineChild(irs.mLineContainer, frame, false,
|
||||
ReparentingDirection::Backwards);
|
||||
ReparentFloatsForInlineChild(irs.mLineContainer, frame, false);
|
||||
}
|
||||
nextInFlow->mFrames.RemoveFirstChild();
|
||||
// nsFirstLineFrame::PullOneFrame calls ReparentComputedStyle.
|
||||
|
|
|
@ -784,8 +784,7 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout,
|
|||
MOZ_ASSERT(newFloatCB, "Must have a float containing block");
|
||||
if (oldFloatCB != newFloatCB) {
|
||||
for (nsIFrame* frame : aColumn) {
|
||||
newFloatCB->ReparentFloats(frame, oldFloatCB, false,
|
||||
ReparentingDirection::Backwards);
|
||||
newFloatCB->ReparentFloats(frame, oldFloatCB, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -421,8 +421,7 @@ nsRubyFrame::PullOneSegment(const nsLineLayout* aLineLayout,
|
|||
if (nsBlockFrame* newFloatCB =
|
||||
nsLayoutUtils::GetAsBlock(aLineLayout->LineContainerFrame())) {
|
||||
if (oldFloatCB && oldFloatCB != newFloatCB) {
|
||||
newFloatCB->ReparentFloats(baseFrame, oldFloatCB, true,
|
||||
ReparentingDirection::Backwards);
|
||||
newFloatCB->ReparentFloats(baseFrame, oldFloatCB, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче