From: L. David Baron Bug 1110277 patch 4 - Pass the aAllowLazyConstruction parameter through to WipeContainingBlock so that we don't do lazy reconstruction when it is forbidden. This patch is not related to fixing the bug, but is similar to patch 5, which is, and also seems like a good idea. diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -7183,17 +7183,17 @@ nsCSSFrameConstructor::ContentAppended(n nsIFrame* prevSibling = ::FindAppendPrevSibling(parentFrame, parentAfterFrame); // Perform special check for diddling around with the frames in // a ib-split inline frame. // If we're appending before :after content, then we're not really // appending, so let WipeContainingBlock know that. LAYOUT_PHASE_TEMP_EXIT(); if (WipeContainingBlock(state, containingBlock, parentFrame, items, - true, prevSibling)) { + true, prevSibling, aAllowLazyConstruction)) { LAYOUT_PHASE_TEMP_REENTER(); return NS_OK; } LAYOUT_PHASE_TEMP_REENTER(); // If the parent is a block frame, and we're not in a special case // where frames can be moved around, determine if the list is for the // start or end of the block. @@ -7724,17 +7724,17 @@ nsCSSFrameConstructor::ContentRangeInser } // Perform special check for diddling around with the frames in // a special inline frame. // If we're appending before :after content, then we're not really // appending, so let WipeContainingBlock know that. LAYOUT_PHASE_TEMP_EXIT(); if (WipeContainingBlock(state, containingBlock, insertion.mParentFrame, items, - isAppend, prevSibling)) { + isAppend, prevSibling, aAllowLazyConstruction)) { LAYOUT_PHASE_TEMP_REENTER(); return NS_OK; } LAYOUT_PHASE_TEMP_REENTER(); // If the container is a table and a caption will be appended, it needs to be // put in the outer table frame's additional child list. // We make no attempt here to set flags to indicate whether the list @@ -11552,60 +11552,61 @@ IsSafeToAppendToIBSplitInline(nsIFrame* } bool nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, nsIFrame* aContainingBlock, nsIFrame* aFrame, FrameConstructionItemList& aItems, bool aIsAppend, - nsIFrame* aPrevSibling) + nsIFrame* aPrevSibling, + bool aAllowLazyConstruction) { if (aItems.IsEmpty()) { return false; } // Before we go and append the frames, we must check for several // special situations. // Situation #1 is a XUL frame that contains frames that are required // to be wrapped in blocks. if (aFrame->IsBoxFrame() && !(aFrame->GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) && aItems.AnyItemsNeedBlockParent()) { - RecreateFramesForContent(aFrame->GetContent(), true, + RecreateFramesForContent(aFrame->GetContent(), aAllowLazyConstruction, REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } nsIFrame* nextSibling = ::GetInsertNextSibling(aFrame, aPrevSibling); // Situation #2 is a flex or grid container frame into which we're inserting // new inline non-replaced children, adjacent to an existing anonymous // flex or grid item. if (::IsFlexOrGridContainer(aFrame)) { FCItemIterator iter(aItems); // Check if we're adding to-be-wrapped content right *after* an existing // anonymous flex or grid item (which would need to absorb this content). if (aPrevSibling && IsAnonymousFlexOrGridItem(aPrevSibling) && iter.item().NeedsAnonFlexOrGridItem(aState)) { - RecreateFramesForContent(aFrame->GetContent(), true, + RecreateFramesForContent(aFrame->GetContent(), aAllowLazyConstruction, REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } // Check if we're adding to-be-wrapped content right *before* an existing // anonymous flex or grid item (which would need to absorb this content). if (nextSibling && IsAnonymousFlexOrGridItem(nextSibling)) { // Jump to the last entry in the list iter.SetToEnd(); iter.Prev(); if (iter.item().NeedsAnonFlexOrGridItem(aState)) { - RecreateFramesForContent(aFrame->GetContent(), true, + RecreateFramesForContent(aFrame->GetContent(), aAllowLazyConstruction, REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } } } // Situation #3 is an anonymous flex or grid item that's getting new children // who don't want to be wrapped. @@ -11623,17 +11624,18 @@ nsCSSFrameConstructor::WipeContainingBlo FCItemIterator iter(aItems); // Skip over things that _do_ need an anonymous flex item, because // they're perfectly happy to go here -- they won't cause a reframe. if (!iter.SkipItemsThatNeedAnonFlexOrGridItem(aState)) { // We hit something that _doesn't_ need an anonymous flex item! // Rebuild the flex container to bust it out. nsIFrame* containerFrame = aFrame->GetParent(); - RecreateFramesForContent(containerFrame->GetContent(), true, + RecreateFramesForContent(containerFrame->GetContent(), + aAllowLazyConstruction, REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } // If we get here, then everything in |aItems| needs to be wrapped in // an anonymous flex or grid item. That's where it's already going - good! } @@ -11794,17 +11796,17 @@ nsCSSFrameConstructor::WipeContainingBlo // it might be empty, so recheck that too. if (aItems.IsEmpty()) { return false; } if (!aItems.AllWantParentType(parentType)) { // Reframing aFrame->GetContent() is good enough, since the content of // table pseudo-frames is the ancestor content. - RecreateFramesForContent(aFrame->GetContent(), true, + RecreateFramesForContent(aFrame->GetContent(), aAllowLazyConstruction, REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } } // Now we have several cases involving {ib} splits. Put them all in a // do/while with breaks to take us to the "go and reconstruct" code. do { @@ -11883,18 +11885,18 @@ nsCSSFrameConstructor::WipeContainingBlo nsIContent *blockContent = aContainingBlock->GetContent(); #ifdef DEBUG if (gNoisyContentUpdates) { printf("nsCSSFrameConstructor::WipeContainingBlock: blockContent=%p\n", static_cast(blockContent)); } #endif - RecreateFramesForContent(blockContent, true, REMOVE_FOR_RECONSTRUCTION, - nullptr); + RecreateFramesForContent(blockContent, aAllowLazyConstruction, + REMOVE_FOR_RECONSTRUCTION, nullptr); return true; } nsresult nsCSSFrameConstructor::ReframeContainingBlock(nsIFrame* aFrame, RemoveFlags aFlags, nsIContent** aDestroyedFramesFor) { diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1728,17 +1728,18 @@ private: // nsFrameManager::InsertFrames directly) to add the new frames. // @return true if we reconstructed the containing block, false // otherwise bool WipeContainingBlock(nsFrameConstructorState& aState, nsIFrame* aContainingBlock, nsIFrame* aFrame, FrameConstructionItemList& aItems, bool aIsAppend, - nsIFrame* aPrevSibling); + nsIFrame* aPrevSibling, + bool aAllowLazyConstruction); nsresult ReframeContainingBlock(nsIFrame* aFrame, RemoveFlags aFlags, nsIContent** aReframeContent); //---------------------------------------- // Methods support :first-letter style