--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -641,16 +641,38 @@ GetIBContainingBlockFor(nsIFrame* aFrame
// post-conditions
NS_ASSERTION(parentFrame, "no normal ancestor found for ib-split frame "
"in GetIBContainingBlockFor");
NS_ASSERTION(parentFrame != aFrame, "parentFrame is actually the child frame - bogus reslt");
return parentFrame;
}
+static nsIFrame*
+GetMulticolContainingBlockFor(nsIFrame* aFrame)
+{
+ NS_PRECONDITION(aFrame->HasMulticolAncestor(),
+ "GetMulticolContainingBlockFor() should only be called on"
+ "frames inside a multicol element!");
+
+ nsIFrame* currFrame = aFrame->GetParent();
+ while (currFrame){
+ // Find the first non-multicol, non-pseudo styled parent frame
+ if (!currFrame->HasMulticolAncestor() &&
+ !currFrame->StyleContext()->GetPseudo()) {
+ break;
+ }
+ currFrame = currFrame->GetParent();
+ }
+
+ MOZ_ASSERT(currFrame, "No valid ColumnSetWrapper in multicol hierarchy!");
+
+ return currFrame;
+}
+
// This is a bit slow, but sometimes we need it.
static bool
ParentIsWrapperAnonBox(nsIFrame* aParent)
{
nsIFrame* maybeAnonBox = aParent;
if (maybeAnonBox->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::cellContent) {
// The thing that would maybe be a wrapper anon box is the cell.
@@ -9174,16 +9196,19 @@ nsCSSFrameConstructor::CreateContinuingF
newFrame = NS_NewXULLabelFrame(shell, styleContext);
newFrame->Init(content, aParentFrame, aFrame);
#endif
} else if (LayoutFrameType::ColumnSet == frameType) {
MOZ_ASSERT(!aFrame->IsTableCaption(),
"no support for fragmenting table captions yet");
newFrame = NS_NewColumnSetFrame(shell, styleContext, nsFrameState(0));
newFrame->Init(content, aParentFrame, aFrame);
+ } else if (LayoutFrameType::ColumnSetWrapper == frameType) {
+ newFrame = NS_NewColumnSetWrapperFrame(shell, styleContext, nsFrameState(0));
+ newFrame->Init(content, aParentFrame, aFrame);
} else if (LayoutFrameType::Page == frameType) {
nsContainerFrame* canvasFrame;
newFrame = ConstructPageFrame(shell, aParentFrame, aFrame, canvasFrame);
} else if (LayoutFrameType::TableWrapper == frameType) {
newFrame =
CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
content, styleContext);
@@ -9551,16 +9576,21 @@ FindPreviousNonWhitespaceSibling(nsIFram
bool
nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "Must have a frame");
NS_PRECONDITION(aFrame->GetParent(), "Frame shouldn't be root");
NS_PRECONDITION(aFrame == aFrame->FirstContinuation(),
"aFrame not the result of GetPrimaryFrame()?");
+ if (aFrame->HasMulticolAncestor()) {
+ ReframeContainingBlock(aFrame);
+ return true;
+ }
+
if (IsFramePartOfIBSplit(aFrame)) {
// The removal functions can't handle removal of an {ib} split directly; we
// need to rebuild the containing block.
#ifdef DEBUG
if (gNoisyContentUpdates) {
printf("nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval: "
"frame=");
nsFrame::ListTag(stdout, aFrame);
@@ -13073,16 +13103,21 @@ nsCSSFrameConstructor::WipeContainingBlo
RecreateFramesForContent(aFrame->GetContent(), InsertionKind::Async);
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 {
+ if (aFrame->HasMulticolAncestor() ||
+ aFrame->Type() == LayoutFrameType::ColumnSetWrapper) {
+ // Need to go ahead and reconstruct.
+ break;
+ }
if (IsInlineFrame(aFrame)) {
if (aItems.AreAllItemsInline()) {
// We can just put the kids in.
return false;
}
if (!IsFramePartOfIBSplit(aFrame)) {
// Need to go ahead and reconstruct.
@@ -13135,21 +13170,22 @@ nsCSSFrameConstructor::WipeContainingBlo
// enforces that the root is display:none, display:table, or display:block.
// Note that walking up "too far" is OK in terms of correctness, even if it
// might be a little inefficient. This is why we walk out of all
// pseudo-frames -- telling which ones are or are not OK to walk out of is
// too hard (and I suspect that we do in fact need to walk out of all of
// them).
while (IsFramePartOfIBSplit(aContainingBlock) ||
aContainingBlock->IsInlineOutside() ||
- aContainingBlock->StyleContext()->GetPseudo()) {
+ aContainingBlock->StyleContext()->GetPseudo() ||
+ aContainingBlock->HasMulticolAncestor()) {
aContainingBlock = aContainingBlock->GetParent();
NS_ASSERTION(aContainingBlock,
- "Must have non-inline, non-ib-split, non-pseudo frame as "
- "root (or child of root, for a table root)!");
+ "Must have non-inline, non-ib-split, non-pseudo, non-multicol"
+ " frame as root (or child of root, for a table root)!");
}
// Tell parent of the containing block to reformulate the
// entire block. This is painful and definitely not optimal
// but it will *always* get the right answer.
nsIContent* blockContent = aContainingBlock->GetContent();
#ifdef DEBUG
@@ -13182,17 +13218,22 @@ nsCSSFrameConstructor::ReframeContaining
if (mPresShell->IsReflowLocked()) {
// don't ReframeContainingBlock, this will result in a crash
// if we remove a tree that's in reflow - see bug 121368 for testcase
NS_ERROR("Atemptted to nsCSSFrameConstructor::ReframeContainingBlock during a Reflow!!!");
return;
}
// Get the first "normal" ancestor of the target frame.
- nsIFrame* containingBlock = GetIBContainingBlockFor(aFrame);
+ nsIFrame* containingBlock = nullptr;
+ if (aFrame->HasMulticolAncestor()) {
+ containingBlock = GetMulticolContainingBlockFor(aFrame);
+ } else {
+ containingBlock = GetIBContainingBlockFor(aFrame);
+ }
if (containingBlock) {
// From here we look for the containing block in case the target
// frame is already a block (which can happen when an inline frame
// wraps some of its content in an anonymous block; see
// ConstructInline)
// NOTE: We used to get the FloatContainingBlock here, but it was often wrong.
// GetIBContainingBlock works much better and provides the correct container in all cases