From f842cc4b961d2852b3be0b98be75c68fde24d1ee Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Fri, 23 Jul 2021 22:52:05 +0000 Subject: [PATCH] Bug 1671527 Part 2 - Make ProcessChildren()'s callers responsible for calling MaybePushFloatContainingBlock(). r=emilio Before this patch, a floating containing block (block frame)'s float descendants are added to its mFloatedList in ~nsFrameConstructorSaveState() after returning from ProcessChildren(). This patch delays that by avoiding calling MaybePushFloatContainingBlock() in ProcessChildren(), and move the call one level up to ProcessChildren()'s callers so that the float descendants are parented to the block frame after leaving the callers. This is similar to how we handle the scope of abspos containing block. This surely adds burden to some of the ProcessChildren() callers, but it also unifies the float containing block scope for those callers utilizing both ConstructFramesFromItemList() and ProcessChildren(). This doesn't change the behavior for now, but it is required by the next part to correctly reparent the float descendants to the correct non-column-span block continuations split by column-span wrappers. Differential Revision: https://phabricator.services.mozilla.com/D120104 --- layout/base/nsCSSFrameConstructor.cpp | 49 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 275f0d058e96..8d69e856ce8e 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1968,6 +1968,10 @@ nsIFrame* nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState, if (display->IsAbsPosContainingBlock(newFrame)) { aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState); } + + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(innerFrame, floatSaveState); + if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) { ConstructFramesFromItemList( aState, aItem.mChildItems, innerFrame, @@ -2040,6 +2044,9 @@ nsIFrame* nsCSSFrameConstructor::ConstructTableRowOrRowGroup( MakeTablePartAbsoluteContainingBlockIfNeeded(aState, aDisplay, absoluteSaveState, newFrame); + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(newFrame, floatSaveState); + nsFrameList childList; if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) { ConstructFramesFromItemList( @@ -2136,14 +2143,11 @@ nsIFrame* nsCSSFrameConstructor::ConstructTableCell( MakeTablePartAbsoluteContainingBlockIfNeeded(aState, aDisplay, absoluteSaveState, newFrame); + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(cellInnerFrame, floatSaveState); + nsFrameList childList; if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) { - // Need to push ourselves as a float containing block. - // XXXbz it might be nice to work on getting the parent - // FrameConstructionItem down into ProcessChildren and just making use of - // the push there, but that's a bit of work. - nsFrameConstructorSaveState floatSaveState; - aState.MaybePushFloatContainingBlock(cellInnerFrame, floatSaveState); ConstructFramesFromItemList( aState, aItem.mChildItems, cellInnerFrame, aItem.mFCData->mBits & FCDATA_IS_WRAPPER_ANON_BOX, childList); @@ -2461,6 +2465,10 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame( NS_ASSERTION(!contentFrame->IsBlockFrameOrSubclass() && !contentFrame->IsFrameOfType(nsIFrame::eSVG), "Only XUL frames should reach here"); + + nsFrameConstructorSaveState floatSaveState; + state.MaybePushFloatContainingBlock(contentFrame, floatSaveState); + ProcessChildren(state, aDocElement, computedStyle, contentFrame, true, childList, false); @@ -3027,6 +3035,9 @@ void nsCSSFrameConstructor::InitializeSelectFrame( RestoreFrameStateFor(scrollFrame, aState.mFrameState); } + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(scrolledFrame, floatSaveState); + // Process children nsFrameList childList; @@ -3119,6 +3130,9 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame( absoluteSaveState); } + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(contentFrame, floatSaveState); + ProcessChildren(aState, content, computedStyle, contentFrame, true, childList, true); nsFrameList fieldsetKids; @@ -3805,10 +3819,10 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal( } } + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(newFrameAsContainer, floatSaveState); + if (bits & FCDATA_USE_CHILD_ITEMS) { - nsFrameConstructorSaveState floatSaveState; - aState.MaybePushFloatContainingBlock(newFrameAsContainer, - floatSaveState); ConstructFramesFromItemList( aState, aItem.mChildItems, newFrameAsContainer, bits & FCDATA_IS_WRAPPER_ANON_BOX, childList); @@ -4797,6 +4811,9 @@ nsContainerFrame* nsCSSFrameConstructor::ConstructFrameWithAnonymousChild( aFrameList); } + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(innerFrame, floatSaveState); + nsFrameList childList; // Process children @@ -7928,6 +7945,9 @@ nsIFrame* nsCSSFrameConstructor::CreateContinuingTableFrame( state, headerFooterComputedStyle->StyleDisplay(), absoluteSaveState, headerFooterFrame); + nsFrameConstructorSaveState floatSaveState; + state.MaybePushFloatContainingBlock(headerFooterFrame, floatSaveState); + ProcessChildren(state, headerFooter, rowGroupFrame->Style(), headerFooterFrame, true, childList, false, nullptr); NS_ASSERTION(state.mFloatedList.IsEmpty(), "unexpected floated element"); @@ -9562,9 +9582,6 @@ void nsCSSFrameConstructor::ProcessChildren( &haveFirstLineStyle); } - nsFrameConstructorSaveState floatSaveState; - aState.MaybePushFloatContainingBlock(aFrame, floatSaveState); - AutoFrameConstructionItemList itemsToConstruct(this); // If we have first-letter or first-line style then frames can get @@ -10525,11 +10542,13 @@ void nsCSSFrameConstructor::ConstructBlock( nsFrameConstructorSaveState absoluteSaveState; (*aNewFrame)->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); if (aPositionedFrameForAbsPosContainer) { - // NS_ASSERTION(aRelPos, "should have made area frame for this"); aState.PushAbsoluteContainingBlock( *aNewFrame, aPositionedFrameForAbsPosContainer, absoluteSaveState); } + nsFrameConstructorSaveState floatSaveState; + aState.MaybePushFloatContainingBlock(blockFrame, floatSaveState); + if (aParentFrame->HasAnyStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR) && !ShouldSuppressColumnSpanDescendants(aParentFrame)) { blockFrame->AddStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR); @@ -11670,6 +11689,10 @@ void nsCSSFrameConstructor::GenerateChildFrames(nsContainerFrame* aFrame) { nsAutoScriptBlocker scriptBlocker; nsFrameList childList; nsFrameConstructorState state(mPresShell, nullptr, nullptr, nullptr); + + nsFrameConstructorSaveState floatSaveState; + state.MaybePushFloatContainingBlock(aFrame, floatSaveState); + ProcessChildren(state, aFrame->GetContent(), aFrame->Style(), aFrame, false, childList, false);