diff options
-rw-r--r-- | layout/base/nsCSSFrameConstructor.cpp | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 8293e5198c..6a512891f9 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -8137,26 +8137,10 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, MOZ_ASSERT(!childFrame || !GetDisplayContentsStyleFor(aChild), "display:contents nodes shouldn't have a frame"); if (!childFrame && GetDisplayContentsStyleFor(aChild)) { - nsIContent* ancestor = aChild->GetFlattenedTreeParent(); - MOZ_ASSERT(ancestor, "display: contents on the root?"); - while (!ancestor->GetPrimaryFrame()) { - ancestor = ancestor->GetFlattenedTreeParent(); - MOZ_ASSERT(ancestor, "we can't have a display: contents subtree root!"); - } - - nsIFrame* ancestorFrame = ancestor->GetPrimaryFrame(); - if (ancestorFrame->GetProperty(nsIFrame::GenConProperty())) { - *aDidReconstruct = true; - - // XXXmats Can we recreate frames only for the ::after/::before content? - // XXX Perhaps even only those that belong to the aChild sub-tree? - LAYOUT_PHASE_TEMP_EXIT(); - RecreateFramesForContent(ancestor, insertionKind, aFlags); - LAYOUT_PHASE_TEMP_REENTER(); - return; - } - - FlattenedChildIterator iter(aChild); + // NOTE(emilio): We may iterate through ::before and ::after here and they + // may be gone after the respective ContentRemoved call. Right now + // StyleChildrenIterator handles that properly, so it's not an issue. + StyleChildrenIterator iter(aChild); for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) { if (c->GetPrimaryFrame() || GetDisplayContentsStyleFor(c)) { LAYOUT_PHASE_TEMP_EXIT(); @@ -8333,8 +8317,13 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, NS_ASSERTION(childFrame, "Missing placeholder frame for out of flow."); parentFrame = childFrame->GetParent(); } + RemoveFrame(nsLayoutUtils::GetChildListNameFor(childFrame), childFrame); + // NOTE(emilio): aChild could be dead here already if it is a ::before or
+ // ::after pseudo-element (since in that case it was owned by childFrame,
+ // which we just destroyed).
+ if (isRoot) { mRootElementFrame = nullptr; mRootElementStyleFrame = nullptr; @@ -8354,8 +8343,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, // to do this if the table parent type of our parent type is not // eTypeBlock, though, because in that case the whitespace isn't // being suppressed due to us anyway. - if (aContainer && !aChild->IsRootOfAnonymousSubtree() && - aFlags == REMOVE_CONTENT && + if (aContainer && aOldNextSibling && aFlags == REMOVE_CONTENT && GetParentType(parentType) == eTypeBlock) { // Adjacent whitespace-only text nodes might have been suppressed if // this node does not have inline ends. Create frames for them now @@ -8370,17 +8358,15 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, // // FIXME(emilio): This should probably use the lazy frame construction // bits if possible instead of reframing it in place. - if (aOldNextSibling) { - nsIContent* prevSibling = aOldNextSibling->GetPreviousSibling(); - if (prevSibling && prevSibling->GetPreviousSibling()) { - LAYOUT_PHASE_TEMP_EXIT(); - ReframeTextIfNeeded(aContainer, prevSibling); - LAYOUT_PHASE_TEMP_REENTER(); - } + nsIContent* prevSibling = aOldNextSibling->GetPreviousSibling(); + if (prevSibling && prevSibling->GetPreviousSibling()) { + LAYOUT_PHASE_TEMP_EXIT(); + ReframeTextIfNeeded(aContainer, prevSibling); + LAYOUT_PHASE_TEMP_REENTER(); } // Reframe any text node just after the node being removed, if there is // one, and if it's not the last child or the first child. - if (aOldNextSibling && aOldNextSibling->GetNextSibling() && + if (aOldNextSibling->GetNextSibling() && aOldNextSibling->GetPreviousSibling()) { LAYOUT_PHASE_TEMP_EXIT(); ReframeTextIfNeeded(aContainer, aOldNextSibling); |