Bug 1411422 - Make percentage block size children work without "height:100%" in ::-moz-column-set and ::-moz-column-content. r=dbaron

After introducing column-span, the ColumnSetWrapperFrame can have more
than one ColumnSetFrame children if there's any column-span:all child.
Thus we cannot use "height:100%" to pass block size information down to
the -moz-column-content's children.

Skip column span wrapper in nsIFrame::IsBlockWrapper() so that the
percentage column-span:all works.

Before this patch, the height of column contents are set to 100% of the
multicol container, so if the previous in-flows of column content
anonymous boxes consume all the height, later in-flows's height are all
0. In this patch, we don't restrict column-content's height, so their
height are calculated based on their children's height.
column-contain-1a.html passes because it can now correctly calculate the
union of all the column content's rect to find the correct sticky
positioning.

Differential Revision: https://phabricator.services.mozilla.com/D27627

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ting-Yu Lin 2019-04-19 22:02:45 +00:00
Родитель 04baf63a80
Коммит b18f4b64c3
9 изменённых файлов: 117 добавлений и 15 удалений

Просмотреть файл

@ -584,7 +584,7 @@ load 1003441.xul
load 1015562.html
asserts(1-2) load 1015563-1.html
asserts(1-2) load 1015563-2.html
asserts(11) asserts-if(Android,274) load 1015844.html # bug 574889, bug 1374479
load 1015844.html
pref(font.size.inflation.minTwips,200) load 1032450.html
load 1032613-1.svg
load 1032613-2.html

Просмотреть файл

@ -3345,9 +3345,30 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
// Construct the reflow input for the block.
Maybe<ReflowInput> blockReflowInput;
blockReflowInput.emplace(
aState.mPresContext, aState.mReflowInput, frame,
availSpace.Size(wm).ConvertTo(frame->GetWritingMode(), wm));
if (Style()->GetPseudoType() == PseudoStyleType::columnContent) {
// Calculate the multicol containing block's block size so that the
// children with percentage block size get correct percentage basis.
const ReflowInput* cbReflowInput =
StaticPrefs::layout_css_column_span_enabled()
? aState.mReflowInput.mParentReflowInput->mCBReflowInput
: aState.mReflowInput.mCBReflowInput;
MOZ_ASSERT(cbReflowInput->mFrame->StyleColumn()->IsColumnContainerStyle(),
"Get unexpected reflow input of multicol containing block!");
// Use column-width as the containing block's inline-size, i.e. the column
// content's computed inline-size.
LogicalSize cbSize = LogicalSize(wm, aState.mReflowInput.ComputedISize(),
cbReflowInput->ComputedBSize())
.ConvertTo(frame->GetWritingMode(), wm);
blockReflowInput.emplace(
aState.mPresContext, aState.mReflowInput, frame,
availSpace.Size(wm).ConvertTo(frame->GetWritingMode(), wm), &cbSize);
} else {
blockReflowInput.emplace(
aState.mPresContext, aState.mReflowInput, frame,
availSpace.Size(wm).ConvertTo(frame->GetWritingMode(), wm));
}
nsFloatManager::SavedState floatManagerState;
nsReflowStatus frameReflowStatus;

Просмотреть файл

@ -312,6 +312,11 @@ nsColumnSetFrame::ReflowConfig nsColumnSetFrame::ChooseColumnStrategy(
colBSize = aReflowInput.ComputedBSize();
} else if (aReflowInput.ComputedMaxBSize() != NS_INTRINSICSIZE) {
colBSize = std::min(colBSize, aReflowInput.ComputedMaxBSize());
} else if (StaticPrefs::layout_css_column_span_enabled() &&
aReflowInput.mCBReflowInput->ComputedMaxBSize() !=
NS_INTRINSICSIZE) {
colBSize =
std::min(colBSize, aReflowInput.mCBReflowInput->ComputedMaxBSize());
}
nscoord colGap = GetColumnGap(this, aReflowInput.ComputedISize());
@ -419,8 +424,9 @@ nsColumnSetFrame::ReflowConfig nsColumnSetFrame::ChooseColumnStrategy(
COLUMN_SET_LOG(
"%s: numColumns=%d, colISize=%d, expectedISizeLeftOver=%d,"
" colBSize=%d, colGap=%d",
__func__, numColumns, colISize, expectedISizeLeftOver, colBSize, colGap);
" colBSize=%d, colGap=%d, isBalancing %d",
__func__, numColumns, colISize, expectedISizeLeftOver, colBSize, colGap,
isBalancing);
ReflowConfig config;
config.mBalanceColCount = numColumns;
@ -705,7 +711,10 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowChildren(
availSize.BSize(wm) = GetAvailableContentBSize(aReflowInput);
}
LogicalSize computedSize = aReflowInput.ComputedSize(wm);
LogicalSize computedSize =
StaticPrefs::layout_css_column_span_enabled()
? aReflowInput.mCBReflowInput->ComputedSize(wm)
: aReflowInput.ComputedSize(wm);
if (reflowNext) child->AddStateBits(NS_FRAME_IS_DIRTY);
@ -720,8 +729,10 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowChildren(
// hasn't changed.
kidReflowInput.mFlags.mMustReflowPlaceholders = !colBSizeChanged;
COLUMN_SET_LOG("%s: Reflowing child #%d %p: availBSize=%d", __func__,
columnCount, child, availSize.BSize(wm));
COLUMN_SET_LOG(
"%s: Reflowing child #%d %p: availSize=(%d,%d), kidCBSize=(%d,%d)",
__func__, columnCount, child, availSize.ISize(wm),
availSize.BSize(wm), kidCBSize.ISize(wm), kidCBSize.BSize(wm));
// Note if the column's next in flow is not being changed by this
// incremental reflow. This may allow the current column to avoid trying
@ -835,7 +846,9 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowChildren(
}
if ((contentBEnd > aReflowInput.ComputedMaxBSize() ||
contentBEnd > aReflowInput.ComputedBSize()) &&
contentBEnd > aReflowInput.ComputedBSize() ||
(StaticPrefs::layout_css_column_span_enabled() &&
contentBEnd > aReflowInput.mCBReflowInput->ComputedMaxBSize())) &&
aConfig.mIsBalancing) {
// We overflowed vertically, but have not exceeded the number of
// columns. We're going to go into overflow columns now, so balancing
@ -1138,6 +1151,10 @@ void nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
MOZ_ASSERT_IF(StaticPrefs::layout_css_column_span_enabled(),
aReflowInput.mCBReflowInput->mFrame->StyleColumn()
->IsColumnContainerStyle());
// Our children depend on our block-size if we have a fixed block-size.
if (aReflowInput.ComputedBSize() != NS_AUTOHEIGHT) {
AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);

Просмотреть файл

@ -7435,7 +7435,8 @@ bool nsIFrame::IsBlockWrapper() const {
auto pseudoType = Style()->GetPseudoType();
return pseudoType == PseudoStyleType::mozBlockInsideInlineWrapper ||
pseudoType == PseudoStyleType::buttonContent ||
pseudoType == PseudoStyleType::cellContent;
pseudoType == PseudoStyleType::cellContent ||
pseudoType == PseudoStyleType::columnSpanWrapper;
}
bool nsIFrame::IsBlockFrameOrSubclass() const {

Просмотреть файл

@ -41,7 +41,7 @@ fuzzy-if(Android,0-4,0-810) == containing-block-1.html containing-block-1-ref.ht
== inline-2.html inline-2-ref.html
fuzzy-if(OSX,0-99,0-210) == inline-3.html inline-3-ref.html
skip-if(!asyncPan) == inline-4.html inline-4-ref.html
fails == column-contain-1a.html column-contain-1-ref.html
== column-contain-1a.html column-contain-1-ref.html
== column-contain-1b.html column-contain-1-ref.html
== column-contain-2.html column-contain-2-ref.html
== block-in-inline-1.html block-in-inline-1-ref.html

Просмотреть файл

@ -256,9 +256,9 @@
text-overflow: inherit;
/* inherit the outer frame's display, otherwise we turn into an inline */
display: inherit;
/* Carry through our parent's height so that %-height children get
their heights set */
height: 100%;
/* -moz-column-set and -moz-column-content's max block size cannot exceed
* ColumnSetWrapperFrame's block size. */
max-block-size: 100%;
}
*|*::-moz-column-set {

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test Reference: Test a multi-column container with percentage height children</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
article {
width: 400px;
height: 200px;
outline: 1px solid black;
}
div {
height: 25%;
}
div.spanner {
outline: 1px solid blue;
height: 50%;
}
</style>
<article>
<div>block1</div>
<div class="spanner">spanner</div>
<div>block2</div>
</article>
</html>

Просмотреть файл

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: Test a multi-column container with percentage height children</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-children-height-001-ref.html">
<meta name="assert" content="This test checks the the percentage height children under multicol container is rendered correctly.">
<style>
article {
column-count: 2;
width: 400px;
height: 200px;
outline: 1px solid black;
}
div {
height: 50%; /* Spread evenly into two colums, each 25%. */
}
div.spanner {
column-span: all;
outline: 1px solid blue;
height: 50%;
}
</style>
<article>
<div>block1</div>
<div class="spanner">spanner</div>
<div>block2</div>
</article>
</html>