Bug 1506163 - Do not span column-span:all element across all columns if it's under different block formatting context. r=bz

multicol-span-all-004-ref.html is the same as multicol-span-all-004.html except
for the "column-span" value in h3.

Differential Revision: https://phabricator.services.mozilla.com/D12192
This commit is contained in:
Ting-Yu Lin 2018-11-16 16:31:22 -08:00
parent 7a12d4d6e9
commit e96e20c21d
7 changed files with 118 additions and 17 deletions

View File

@ -0,0 +1,7 @@
<li style="column-count: 1">
<summary style="overflow-x: scroll">
<div style="column-span: all">
<canvas>
<meta
charset="UTF-8"
<!-- a -->

View File

@ -548,4 +548,5 @@ load 1490037.html
load 1494332.html
load 1494030.html
load 1505420.html
pref(layout.css.column-span.enabled,true) load 1506163.html
pref(layout.css.column-span.enabled,true) load 1506204.html

View File

@ -11174,14 +11174,17 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
}
// Ensure all the children in the multi-column subtree are tagged with
// NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR, except for those children in the
// column-span subtree. InitAndRestoreFrame() will add
// NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR, except for those children in a new
// block formatting context. InitAndRestoreFrame() will add
// mAdditionalStateBits for us.
AutoRestore<nsFrameState> savedStateBits(aState.mAdditionalStateBits);
if (StaticPrefs::layout_css_column_span_enabled()) {
// Multi-column container creates new block formatting context, so check
// needsColumn first to make sure we have the bit set when creating frames
// for the elements having style like "columns:3; column-span:all;".
if (needsColumn) {
aState.mAdditionalStateBits |= NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR;
} else if (blockFrame->IsColumnSpan()) {
} else if (blockFrame->HasAllStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS)) {
aState.mAdditionalStateBits &= ~NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR;
}
}
@ -11392,14 +11395,22 @@ nsCSSFrameConstructor::MayNeedToCreateColumnSpanSiblings(
MOZ_ASSERT(StaticPrefs::layout_css_column_span_enabled(),
"Call this only when layout.css.column-span.enabled is true!");
if (aBlockFrame->IsColumnSpan() ||
!aBlockFrame->HasAnyStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR)) {
// The children of a column-span never need to be further processed even
// if there is a nested column-span child. Because a column-span always
// creates its own block formatting context, a nested column-span child
// won't be in the same block formatting context with the nearest
// multi-column ancestor. This is the same case as if the column-span is
// outside of a multi-column hierarchy.
if (!aBlockFrame->HasAnyStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR)) {
// The block frame isn't in a multi-column block formatting context.
return false;
}
if (aBlockFrame->HasAllStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS) &&
aBlockFrame->Style()->GetPseudo() != nsCSSAnonBoxes::columnContent()) {
// The block creates its own block formatting context, and is not the block
// representing actual column contents.
//
// For example, the children of a column-span never need to be further
// processed even if there is a nested column-span child. Because a
// column-span always creates its own block formatting context, a nested
// column-span child won't be in the same block formatting context with the
// nearest multi-column ancestor. This is the same case as if the
// column-span is outside of a multi-column hierarchy.
return false;
}
@ -11419,7 +11430,7 @@ nsCSSFrameConstructor::MayNeedToCreateColumnSpanSiblings(
return false;
}
// Need to actually look into the child items.
// Need to actually look into the child list.
return true;
}

View File

@ -225,11 +225,14 @@ FRAME_STATE_BIT(Generic, 42, NS_FRAME_FONT_INFLATION_FLOW_ROOT)
FRAME_STATE_BIT(Generic, 43, NS_FRAME_SVG_LAYOUT)
// This bit is set if a frame has a multi-column ancestor (i.e.
// ColumnSetWrapperFrame) within the same block formatting context. A
// top-level ColumnSetWrapperFrame doesn't have this bit set, whereas a
// ColumnSetWrapperFrame nested inside a column does have this bit set. All
// the children of the column-spans do not have this bit set because they
// are in a new block formatting context created by column-spans.
// ColumnSetWrapperFrame) within the same block formatting context. A top-level
// ColumnSetWrapperFrame doesn't have this bit set, whereas a
// ColumnSetWrapperFrame nested inside a column does have this bit set.
//
// All the children of the column-spanners or any other type of frames which
// create their own block formatting context do not have this bit set because
// they are not in the same block formatting context created by a multi-column
// ancestor.
FRAME_STATE_BIT(Generic, 44, NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR)
// Bits 45 is currently unused, but be kind and check with bug 1465474

View File

@ -0,0 +1,2 @@
[multicol-span-all-004.html]
prefs: [layout.css.column-span.enabled:true]

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test Reference: column-span:all should act like column-span:none in different block formatting context</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
#column {
column-count: 3;
column-rule: 6px solid;
width: 600px;
outline: 1px solid black;
}
h3 {
column-span: none;
outline: 1px solid blue;
}
</style>
<body onload="runTest();">
<article id="column">
<div>block1</div>
<div style="display: inline-block;">
<h3>non-spanner</h3>
</div>
<div style="overflow: hidden;">
<h3>non-spanner</h3>
</div>
<div style="column-span: all; outline: 1px solid green;">
Spanner
<h3>non-spanner in a spanner</h3>
</div>
<div>block2</div>
</article>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: column-span:all should act like column-span:none in different block formatting context</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
<link rel="match" href="multicol-span-all-004-ref.html">
<meta name="assert" content="This test checks a column-span:all element should act like column-span: none if it's under different block formatting context.">
<style>
#column {
column-count: 3;
column-rule: 6px solid;
width: 600px;
outline: 1px solid black;
}
h3 {
column-span: all;
outline: 1px solid blue;
}
</style>
<body onload="runTest();">
<article id="column">
<div>block1</div>
<div style="display: inline-block;">
<h3>non-spanner</h3>
</div>
<div style="overflow: hidden;">
<h3>non-spanner</h3>
</div>
<div style="column-span: all; outline: 1px solid green;">
Spanner
<h3>non-spanner in a spanner</h3>
</div>
<div>block2</div>
</article>
</body>
</html>