Bug 1429961: Make sure to remove all the continuations with the same PostDestroyData. r?mats
If we remove the first continuation of the ::after content before the last,
before this patch unbind the generated content ASAP. Part of the generated
content (the second counter) in the test-case ends up in a continuation of that
frame.
That text node would already be unbound from the tree when destroying its
frame.
MozReview-Commit-ID: 4VtVRSoGxCT
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -156,24 +156,25 @@ nsContainerFrame::RemoveFrame(ChildListI
// Request a reflow on the parent frames involved unless we were explicitly
// told not to (kNoReflowPrincipalList).
bool generateReflowCommand = true;
if (kNoReflowPrincipalList == aListID) {
generateReflowCommand = false;
}
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.
// We really MUST use StealFrame() and nothing else here.
// @see nsInlineFrame::StealFrame for details.
parent->StealFrame(aOldFrame);
- aOldFrame->Destroy();
+ aOldFrame->Destroy(data.mData);
aOldFrame = oldFrameNextContinuation;
if (parent != lastParent && generateReflowCommand) {
shell->FrameNeedsReflow(parent, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
lastParent = parent;
}
}
}
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -679,17 +679,25 @@ public:
* Destroy() for each child). If this frame is a first-continuation, this
* also removes the frame from the primary frame map and clears undisplayed
* content for its content node.
* If the frame is a placeholder, it also ensures the out-of-flow frame's
* removal and destruction.
*/
void Destroy() {
AutoPostDestroyData data(PresContext());
- DestroyFrom(this, data.mData);
+ 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);
// Note that |this| is deleted at this point.
}
/** Flags for PeekOffsetCharacter, PeekOffsetNoAmount, PeekOffsetWord return values.
*/
enum FrameSearchResult {
// Peek found a appropriate offset within frame.
FOUND = 0x00,