Bug 1429961: Destroy continuations last-to-first. r=mats

MozReview-Commit-ID: Ftc8NJLTaAw

--HG--
extra : rebase_source : bfe1e6be81b460b320145fa345b722775db24f4c
This commit is contained in:
Emilio Cobos Álvarez 2018-01-15 21:39:03 +01:00
Родитель 03f4a1ab69
Коммит b2223e5580
2 изменённых файлов: 23 добавлений и 26 удалений

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

@ -152,26 +152,32 @@ nsContainerFrame::RemoveFrame(ChildListID aListID,
MOZ_ASSERT(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
"unexpected child list");
// Loop and destroy aOldFrame and all of its continuations.
// Request a reflow on the parent frames involved unless we were explicitly
// told not to (kNoReflowPrincipalList).
bool generateReflowCommand = true;
if (kNoReflowPrincipalList == aListID) {
generateReflowCommand = false;
AutoTArray<nsIFrame*, 10> continuations;
{
nsIFrame* continuation = aOldFrame;
while (continuation) {
continuations.AppendElement(continuation);
continuation = continuation->GetNextContinuation();
}
}
nsIPresShell* shell = PresShell();
nsContainerFrame* lastParent = nullptr;
AutoPostDestroyData data(PresContext());
while (aOldFrame) {
nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation();
nsContainerFrame* parent = aOldFrame->GetParent();
// Please note that 'parent' may not actually be where 'aOldFrame' lives.
// Loop and destroy aOldFrame and all of its continuations.
//
// Request a reflow on the parent frames involved unless we were explicitly
// told not to (kNoReflowPrincipalList).
const bool generateReflowCommand = (kNoReflowPrincipalList != aListID);
for (nsIFrame* continuation : Reversed(continuations)) {
nsContainerFrame* parent = continuation->GetParent();
// Please note that 'parent' may not actually be where 'continuation' lives.
// We really MUST use StealFrame() and nothing else here.
// @see nsInlineFrame::StealFrame for details.
parent->StealFrame(aOldFrame);
aOldFrame->Destroy(data.mData);
aOldFrame = oldFrameNextContinuation;
if (parent != lastParent && generateReflowCommand) {
parent->StealFrame(continuation);
continuation->Destroy();
if (generateReflowCommand && parent != lastParent) {
shell->FrameNeedsReflow(parent, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
lastParent = parent;
@ -1410,8 +1416,7 @@ nsContainerFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
for (nsIFrame* f = nextNextInFlow; f; f = f->GetNextInFlow()) {
frames.AppendElement(f);
}
for (int32_t i = frames.Length() - 1; i >= 0; --i) {
nsIFrame* delFrame = frames.ElementAt(i);
for (nsIFrame* delFrame : Reversed(frames)) {
delFrame->GetParent()->
DeleteNextInFlowChild(delFrame, aDeletingEmptyFrames);
}

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

@ -684,15 +684,7 @@ public:
*/
void Destroy() {
AutoPostDestroyData data(PresContext());
Destroy(data.mData);
// Note that |this| is deleted at this point.
}
/**
* Pretty much like Destroy() but with a provided PostDestroyData.
*/
void Destroy(PostDestroyData& aPostDestroyData) {
DestroyFrom(this, aPostDestroyData);
DestroyFrom(this, data.mData);
// Note that |this| is deleted at this point.
}