From 0cfeee90dcc45b16729687f2b17864cdfe901d1e Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Tue, 3 Jul 2018 08:20:14 -0700 Subject: [PATCH] #506: M984869 M1308793 M1316649 --- layout/base/nsCSSFrameConstructor.cpp | 81 ++++++++++++++++++++------- layout/base/nsCSSFrameConstructor.h | 6 ++ layout/generic/nsHTMLReflowState.cpp | 5 ++ 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 263a97c57..c33dab312 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3423,7 +3423,8 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement, SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame), SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame), { &nsGkAtoms::button, - FCDATA_WITH_WRAPPING_BLOCK(FCDATA_ALLOW_BLOCK_STYLES, + FCDATA_WITH_WRAPPING_BLOCK(FCDATA_ALLOW_BLOCK_STYLES | + FCDATA_ALLOW_GRID_FLEX_COLUMNSET, NS_NewHTMLButtonControlFrame, nsCSSAnonBoxes::buttonContent) }, SIMPLE_TAG_CHAIN(canvas, nsCSSFrameConstructor::FindCanvasData), @@ -3710,34 +3711,74 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt nsIFrame* maybeAbsoluteContainingBlock = newFrame; nsIFrame* possiblyLeafFrame = newFrame; if (bits & FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS) { - RefPtr blockContext; - blockContext = + RefPtr outerSC = mPresShell->StyleSet()->ResolveAnonymousBoxStyle(*data->mAnonBoxPseudo, styleContext); - nsIFrame* blockFrame = - NS_NewBlockFormattingContext(mPresShell, blockContext); - #ifdef DEBUG nsContainerFrame* containerFrame = do_QueryFrame(newFrame); MOZ_ASSERT(containerFrame); #endif nsContainerFrame* container = static_cast(newFrame); - InitAndRestoreFrame(aState, content, container, blockFrame); - - SetInitialSingleChild(container, blockFrame); - - // Now figure out whether newFrame or blockFrame should be the - // absolute container. It should be the latter if it's - // positioned, otherwise the former. - const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay(); - if (blockDisplay->IsAbsPosContainingBlock(blockFrame)) { - maybeAbsoluteContainingBlockDisplay = blockDisplay; - maybeAbsoluteContainingBlock = blockFrame; - maybeAbsoluteContainingBlockStyleFrame = blockFrame; + nsContainerFrame* outerFrame; + nsContainerFrame* innerFrame; + if (bits & FCDATA_ALLOW_GRID_FLEX_COLUMNSET) { + switch (display->mDisplay) { + case NS_STYLE_DISPLAY_FLEX: + case NS_STYLE_DISPLAY_INLINE_FLEX: + outerFrame = NS_NewFlexContainerFrame(mPresShell, outerSC); + InitAndRestoreFrame(aState, content, container, outerFrame); + innerFrame = outerFrame; + break; + case NS_STYLE_DISPLAY_GRID: + case NS_STYLE_DISPLAY_INLINE_GRID: + outerFrame = NS_NewGridContainerFrame(mPresShell, outerSC); + InitAndRestoreFrame(aState, content, container, outerFrame); + innerFrame = outerFrame; + break; + default: { + nsContainerFrame* columnSetFrame = nullptr; + RefPtr innerSC = outerSC; + const nsStyleColumn* columns = outerSC->StyleColumn(); + if (columns->mColumnCount != NS_STYLE_COLUMN_COUNT_AUTO || + columns->mColumnWidth.GetUnit() != eStyleUnit_Auto) { + columnSetFrame = + NS_NewColumnSetFrame(mPresShell, outerSC, nsFrameState(0)); + InitAndRestoreFrame(aState, content, container, columnSetFrame); + innerSC = mPresShell->StyleSet()->ResolveAnonymousBoxStyle( + nsCSSAnonBoxes::columnContent, outerSC); + } + innerFrame = NS_NewBlockFormattingContext(mPresShell, innerSC); + if (columnSetFrame) { + InitAndRestoreFrame(aState, content, columnSetFrame, innerFrame); + SetInitialSingleChild(columnSetFrame, innerFrame); + outerFrame = columnSetFrame; + } else { + InitAndRestoreFrame(aState, content, container, innerFrame); + outerFrame = innerFrame; + } + break; + } + } + } else { + innerFrame = NS_NewBlockFormattingContext(mPresShell, outerSC); + InitAndRestoreFrame(aState, content, container, innerFrame); + outerFrame = innerFrame; } - // Our kids should go into the blockFrame - newFrame = blockFrame; + SetInitialSingleChild(container, outerFrame); + + // Now figure out whether newFrame or outerFrame should be the + // absolute container. + auto outerDisplay = outerSC->StyleDisplay(); + if (outerDisplay->IsAbsPosContainingBlock(outerFrame)) { + maybeAbsoluteContainingBlockDisplay = outerDisplay; + maybeAbsoluteContainingBlock = outerFrame; + maybeAbsoluteContainingBlockStyleFrame = outerFrame; + innerFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); + } + + // Our kids should go into the innerFrame. + newFrame = innerFrame; } aState.AddChild(frameToAddToList, aFrameItems, content, styleContext, diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 8a12253a6..91a3b3986 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -688,6 +688,12 @@ private: * display:contents */ #define FCDATA_IS_CONTENTS 0x100000 + /** + * When FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, this bit says + * if we should create a grid/flex/columnset container instead of + * a block wrapper when the styles says so. + */ +#define FCDATA_ALLOW_GRID_FLEX_COLUMNSET 0x200000 /* Structure representing information about how a frame should be constructed. */ diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index a21f18f4a..581885fc4 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -478,6 +478,11 @@ void nsHTMLReflowState::InitCBReflowState() mCBReflowState = nullptr; return; } + if (parentReflowState->mFlags.mDummyParentReflowState) { + // from bug 1316649 + mCBReflowState = parentReflowState; + return; + } if (parentReflowState->frame == frame->GetContainingBlock()) { // Inner table frames need to use the containing block of the outer