Bug 1548100 Part 2 - Fix the block-size of the column-rule by consuming available block-size. r=dbaron

After enabling column-span, ColumnSet becomes an anonymous child under
ColumnSetWrapperFrame. It doesn't need to handle border and padding,
containment, and non-auto block-size. ColumnSet's final block-size is
simply the union of ::-moz-column-content frames' rects.

However, we should extend ColumnSet's block-size to consume the
available block-size if the ColumnSetWrapper's block-size is constrained
so that the column rules are drawn to the block-end edge of the multicol
container.

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

--HG--
rename : testing/web-platform/meta/css/css-multicol/multicol-breaking-000.html.ini => testing/web-platform/meta/css/css-multicol/multicol-rule-nested-balancing-001.html.ini
rename : testing/web-platform/meta/css/css-multicol/multicol-breaking-000.html.ini => testing/web-platform/meta/css/css-multicol/multicol-rule-nested-balancing-002.html.ini
rename : testing/web-platform/meta/css/css-multicol/multicol-breaking-000.html.ini => testing/web-platform/meta/css/css-multicol/multicol-span-all-rule-001.html.ini
extra : moz-landing-system : lando
This commit is contained in:
Ting-Yu Lin 2019-08-01 00:03:22 +00:00
parent 5ae0a79947
commit e65d961df7
20 changed files with 323 additions and 35 deletions

View File

@ -10803,6 +10803,9 @@ void nsCSSFrameConstructor::FinishBuildingColumns(
nsFrameList finalList;
while (aColumnContentSiblings.NotEmpty()) {
// Tag every ColumnSet except the last one.
prevColumnSet->SetProperty(nsIFrame::HasColumnSpanSiblings(), true);
nsIFrame* f = aColumnContentSiblings.RemoveFirstChild();
if (f->IsColumnSpan()) {
// Do nothing for column-span wrappers. Just move it to the final

View File

@ -3573,6 +3573,8 @@ void nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
availSize.BSize(wm) -= aState.BorderPadding().BEnd(wm);
}
// Bug 1569701: We need to use GetEffectiveComputedBSize() to get
// correct block-size if ColumnSetWrapper is fragmented.
nscoord contentBSize = aState.mReflowInput.ComputedBSize();
if (aState.mReflowInput.ComputedMaxBSize() != NS_UNCONSTRAINEDSIZE) {
contentBSize =

View File

@ -917,37 +917,71 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowChildren(
contentSize.BSize(wm) = std::max(contentSize.BSize(wm), contentBEnd);
mLastFrameStatus = aStatus;
// Apply computed and min/max values
if (aConfig.mComputedBSize != NS_UNCONSTRAINEDSIZE) {
if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE) {
if (StaticPrefs::layout_css_column_span_enabled()) {
MOZ_ASSERT(borderPadding.IsAllZero(),
"Only our parent ColumnSetWrapper can have border and padding!");
if (computedSize.BSize(wm) != NS_UNCONSTRAINEDSIZE &&
!GetProperty(nsIFrame::HasColumnSpanSiblings())) {
MOZ_ASSERT(aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE,
"Available block-size should be constrained because it's "
"restricted by the computed block-size when our reflow input "
"is created in nsBlockFrame::ReflowBlockFrame()!");
// If a) our parent ColumnSetWrapper has constrained block-size
// (nsBlockFrame::ReflowBlockFrame() applies the block-size constraint
// when creating BlockReflowInput for ColumnSetFrame); and b) we are the
// sole ColumnSet or the last ColumnSet continuation split by column-spans
// in a ColumnSetWrapper, extend our block-size to consume the available
// block-size so that the column-rules are drawn to the content block-end
// edge of the multicol container.
contentSize.BSize(wm) =
std::min(contentSize.BSize(wm), aConfig.mComputedBSize);
} else {
contentSize.BSize(wm) = aConfig.mComputedBSize;
std::max(contentSize.BSize(wm), aReflowInput.AvailableBSize());
// But don't consume more block-size than what is left in the
// ColumnSetWrapper.
//
// Bug 1569701: If we use the effective computed block-size of
// ColumnSetWrapper when creating BlockReflowInput for ColumnSet, the
// available block-size should always less than or equal to the effective
// computed block-size. This std::min() won't be needed.
contentSize.BSize(wm) =
std::min(contentSize.BSize(wm), computedSize.BSize(wm));
}
} else if (aReflowInput.mStyleDisplay->IsContainSize()) {
// If we are intrinsically sized, but are size contained,
// we need to behave as if we have no contents. Our BSize
// should be zero or minBSize if specified.
contentSize.BSize(wm) = aReflowInput.ApplyMinMaxBSize(0);
} else {
// We add the "consumed" block-size back in so that we're applying
// constraints to the correct bSize value, then subtract it again
// after we've finished with the min/max calculation. This prevents us from
// having a last continuation that is smaller than the min bSize. but which
// has prev-in-flows, trigger a larger bSize than actually required.
contentSize.BSize(wm) = aReflowInput.ApplyMinMaxBSize(
contentSize.BSize(wm), aConfig.mConsumedBSize);
}
if (aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE) {
contentSize.ISize(wm) = aReflowInput.ComputedISize();
} else {
contentSize.ISize(wm) =
aReflowInput.ApplyMinMaxISize(contentSize.ISize(wm));
// Apply computed and min/max values
if (aConfig.mComputedBSize != NS_UNCONSTRAINEDSIZE) {
if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE) {
contentSize.BSize(wm) =
std::min(contentSize.BSize(wm), aConfig.mComputedBSize);
} else {
contentSize.BSize(wm) = aConfig.mComputedBSize;
}
} else if (aReflowInput.mStyleDisplay->IsContainSize()) {
// If we are intrinsically sized, but are size contained,
// we need to behave as if we have no contents. Our BSize
// should be zero or minBSize if specified.
contentSize.BSize(wm) = aReflowInput.ApplyMinMaxBSize(0);
} else {
// We add the "consumed" block-size back in so that we're applying
// constraints to the correct bSize value, then subtract it again
// after we've finished with the min/max calculation. This prevents us
// from having a last continuation that is smaller than the min bSize. but
// which has prev-in-flows, trigger a larger bSize than actually required.
contentSize.BSize(wm) = aReflowInput.ApplyMinMaxBSize(
contentSize.BSize(wm), aConfig.mConsumedBSize);
}
if (aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE) {
contentSize.ISize(wm) = aReflowInput.ComputedISize();
} else {
contentSize.ISize(wm) =
aReflowInput.ApplyMinMaxISize(contentSize.ISize(wm));
}
contentSize.ISize(wm) += borderPadding.IStartEnd(wm);
contentSize.BSize(wm) += borderPadding.BStartEnd(wm);
}
contentSize.ISize(wm) += borderPadding.IStartEnd(wm);
contentSize.BSize(wm) += borderPadding.BStartEnd(wm);
aDesiredSize.SetSize(wm, contentSize);
aDesiredSize.mOverflowAreas = overflowRects;
aDesiredSize.UnionOverflowAreasWithDesiredBounds();

View File

@ -49,7 +49,7 @@ pref(layout.css.column-span.enabled,true) == first-line-first-letter.html first-
# column-span enabled. These lines can be removed once the pref becomes
# default-enabled (Bug 1426010).
default-preferences pref(layout.css.column-span.enabled,true)
fails == min-width-2.html min-width-2-ref.html # Bug 1548100
== min-width-2.html min-width-2-ref.html
== column-balancing-nested-001.html column-balancing-nested-001-ref.html
fails == zero-height-nondirty-reflow.html zero-height-nondirty-reflow-ref.html # bug 1565665
default-preferences

View File

@ -260,8 +260,7 @@ css-multicol/multicol-rule-000.xht
fuzzy-if(!OSX,0-135,0-1584) css-multicol/multicol-rule-001.xht
fails-if(!OSX) random-if(OSX) css-multicol/multicol-rule-002.xht
css-multicol/multicol-rule-003.xht
# Bug 1548100
pref(layout.css.column-span.enabled,true) fails css-multicol/multicol-rule-004.xht
pref(layout.css.column-span.enabled,true) css-multicol/multicol-rule-004.xht
css-multicol/multicol-rule-color-001.xht
fuzzy(0-106,0-354) css-multicol/multicol-rule-dashed-000.xht
fuzzy(0-106,0-354) css-multicol/multicol-rule-dotted-000.xht

View File

@ -125,7 +125,7 @@ fuzzy-if(skiaContent,0-64,0-2) == css-multicol/multicol-reduce-000.xht css-multi
fuzzy-if(!OSX,0-135,0-1584) == css-multicol/multicol-rule-001.xht css-multicol/multicol-rule-001-ref.xht
fails-if(!OSX) random-if(OSX) == css-multicol/multicol-rule-002.xht css-multicol/multicol-rule-ref.xht
== css-multicol/multicol-rule-003.xht css-multicol/multicol-rule-003-ref.xht
pref(layout.css.column-span.enabled,true) fails == css-multicol/multicol-rule-004.xht css-multicol/multicol-rule-004-ref.xht
pref(layout.css.column-span.enabled,true) == css-multicol/multicol-rule-004.xht css-multicol/multicol-rule-004-ref.xht
== css-multicol/multicol-rule-color-001.xht css-multicol/multicol-rule-color-001-ref.xht
== css-multicol/multicol-rule-color-inherit-001.xht css-multicol/multicol-rule-color-inherit-001-ref.xht
== css-multicol/multicol-rule-color-inherit-002.xht css-multicol/multicol-rule-color-inherit-001-ref.xht

View File

@ -1,3 +1,2 @@
[multicol-breaking-000.html]
prefs: [layout.css.column-span.enabled:true]
expected: FAIL

View File

@ -1,3 +1,2 @@
[multicol-breaking-001.html]
prefs: [layout.css.column-span.enabled:true]
expected: FAIL

View File

@ -1,3 +1,2 @@
[multicol-breaking-004.html]
prefs: [layout.css.column-span.enabled:true]
expected: FAIL

View File

@ -1,3 +1,2 @@
[multicol-breaking-nobackground-000.html]
prefs: [layout.css.column-span.enabled:true]
expected: FAIL

View File

@ -1,3 +1,2 @@
[multicol-breaking-nobackground-001.html]
prefs: [layout.css.column-span.enabled:true]
expected: FAIL

View File

@ -0,0 +1,2 @@
[multicol-rule-nested-balancing-001.html]
prefs: [layout.css.column-span.enabled:true]

View File

@ -0,0 +1,2 @@
[multicol-rule-nested-balancing-002.html]
prefs: [layout.css.column-span.enabled:true]

View File

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

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test Reference: Test the column rules' block-size with nested balancing multicol container</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<style>
.outer {
column-count: 2;
column-rule: 6px solid black;
column-fill: auto;
width: 400px;
height: 250px;
}
.inner {
column-count: 2;
column-rule: 3px solid gray;
column-fill: auto;
height: 200px;
}
.outer-block {
background-color: lightgreen;
height: 200px;
}
.inner-block {
background-color: lightblue;
height: 150px;
}
.space {
height: 50px;
}
</style>
<article class="outer">
<div class="outer-block"></div>
<div class="space"></div>
<article class="inner">
<div class="inner-block"></div><div class="space"></div>
<div class="inner-block"></div><div class="space"></div>
</article>
</article>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: Test the column rules' block-size with nested balancing multicol container</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#cf">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-gaps-and-rules">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2309">
<link rel="match" href="multicol-rule-nested-balancing-001-ref.html">
<meta name="assert" content="This test verifies that the column-rules are extended to the content block-end edges of their corresponding inner and outer multicol container.">
<style>
.outer {
column-count: 2;
column-rule: 6px solid black;
width: 400px;
height: 250px;
}
.inner {
column-count: 2;
column-rule: 3px solid gray;
height: 200px;
}
.outer-block {
background-color: lightgreen;
height: 200px;
}
.inner-block {
background-color: lightblue;
height: 300px;
}
</style>
<article class="outer">
<div class="outer-block"></div>
<article class="inner">
<div class="inner-block"></div>
</article>
</article>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test Reference: Test the column rules' block-size with nested balancing multicol container</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<style>
.outer {
column-count: 2;
column-rule: 6px solid black;
column-fill: auto;
width: 400px;
height: 250px;
}
.inner {
column-count: 2;
column-rule: 3px solid gray;
column-fill: auto;
height: 200px;
}
.outer-block {
background-color: lightgreen;
height: 200px;
}
.inner-block {
background-color: lightblue;
height: 200px;
}
.space {
height: 50px;
}
</style>
<article class="outer">
<div class="outer-block"></div>
<div class="space"></div>
<article class="inner">
<div class="inner-block"></div>
<div class="inner-block"></div>
</article>
</article>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: Test the column rules' block-size with nested balancing multicol container</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#cf">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-gaps-and-rules">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2309">
<link rel="match" href="multicol-rule-nested-balancing-002-ref.html">
<meta name="assert" content="This test verifies that the column-rules are extended to the content block-end edges of their corresponding inner and outer multicol container, where the inner container has height: auto.">
<style>
.outer {
column-count: 2;
column-rule: 6px solid black;
width: 400px;
height: 250px;
}
.inner {
column-count: 2;
column-rule: 3px solid gray;
height: auto;
}
.outer-block {
background-color: lightgreen;
height: 200px;
}
.inner-block {
background-color: lightblue;
height: 400px;
}
</style>
<article class="outer">
<div class="outer-block"></div>
<article class="inner">
<div class="inner-block"></div>
</article>
</article>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: Test the column-rule's block-size</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<style>
article {
column-count: 2;
column-rule: 6px solid;
width: 400px;
height: 500px;
background-color: lightgreen;
border: 2em solid purple;
padding: 2em;
}
div.block {
width: 100px;
height: 200px;
}
div.column-span {
column-span: all;
height: 50px;
background-color: lightblue;
}
</style>
<article>
<div class="block">block1</div>
<div class="column-span">column-span1</div>
<div class="block">block2</div>
<div class="column-span">column-span2</div>
<div class="block" style="height: 400px;">block3</div>
</article>
</html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>CSS Multi-column Layout Test: Test the column rule's block-size</title>
<link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
<link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-gaps-and-rules">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2309">
<link rel="match" href="multicol-span-all-rule-001-ref.html">
<meta name="assert" content="This test verifies that the column-rule after the last column-span is extended to the content block-end edge of the multicol container.">
<style>
article {
column-count: 2;
column-rule: 6px solid;
width: 400px;
height: 500px;
background-color: lightgreen;
border: 2em solid purple;
padding: 2em;
}
div.block {
width: 100px;
height: 200px;
}
div.column-span {
column-span: all;
height: 50px;
background-color: lightblue;
}
</style>
<article>
<!-- Each block spreads its height evenly into two columns, and
each column contains 100px height. -->
<div class="block">block1</div>
<div class="column-span">column-span1</div>
<div class="block">block2</div>
<div class="column-span">column-span2</div>
<!-- The column rule after column-span2 should extend to the content edge
of the multicol container as if block3 has "height: 400px;" -->
<div class="block">block3</div>
</article>
</html>