Bug 1467209 - Implement contain:size for blockFrame, add reftests.
MozReview-Commit-ID: 9lDZkAllu8I
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -484,16 +484,20 @@ bool
nsBlockFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup,
nscoord* aBaseline) const
{
if (aBaselineGroup == BaselineSharingGroup::eFirst) {
return nsLayoutUtils::GetFirstLineBaseline(aWM, this, aBaseline);
}
+ if (StyleDisplay()->IsContainSize()) {
+ return false;
+ }
+
for (ConstReverseLineIterator line = LinesRBegin(), line_end = LinesREnd();
line != line_end; ++line) {
if (line->IsBlock()) {
nscoord offset;
nsIFrame* kid = line->mFirstChild;
if (kid->GetVerticalAlignBaseline(aWM, &offset)) {
// Ignore relative positioning for baseline calculations.
const nsSize& sz = line->mContainerSize;
@@ -696,16 +700,21 @@ nsBlockFrame::GetMinISize(gfxContext *aR
DISPLAY_MIN_WIDTH(this, mMinWidth);
CheckIntrinsicCacheAgainstShrinkWrapState();
if (mMinWidth != NS_INTRINSIC_WIDTH_UNKNOWN)
return mMinWidth;
+ if (StyleDisplay()->IsContainSize()) {
+ mMinWidth = 0;
+ return mMinWidth;
+ }
+
#ifdef DEBUG
if (gNoisyIntrinsic) {
IndentBy(stdout, gNoiseIndent);
ListTag(stdout);
printf(": GetMinISize\n");
}
AutoNoisyIndenter indenter(gNoisyIntrinsic);
#endif
@@ -784,16 +793,21 @@ nsBlockFrame::GetPrefISize(gfxContext *a
DISPLAY_PREF_WIDTH(this, mPrefWidth);
CheckIntrinsicCacheAgainstShrinkWrapState();
if (mPrefWidth != NS_INTRINSIC_WIDTH_UNKNOWN)
return mPrefWidth;
+ if (StyleDisplay()->IsContainSize()) {
+ mPrefWidth = 0;
+ return mPrefWidth;
+ }
+
#ifdef DEBUG
if (gNoisyIntrinsic) {
IndentBy(stdout, gNoiseIndent);
ListTag(stdout);
printf(": GetPrefISize\n");
}
AutoNoisyIndenter indenter(gNoisyIntrinsic);
#endif
@@ -1618,16 +1632,27 @@ nsBlockFrame::ComputeFinalSize(const Ref
// on its own on the last-in-flow, even if we ran out of height
// here. We need GetSkipSides to check whether we ran out of content
// height in the current frame, not whether it's last-in-flow.
}
// Don't carry out a block-end margin when our BSize is fixed.
aMetrics.mCarriedOutBEndMargin.Zero();
}
+ else if (aReflowInput.mStyleDisplay->IsContainSize()) {
+ // If we're size-containing and we don't have a specified size, then our
+ // final size should actually be computed from only our border and padding,
+ // as though we were empty.
+ // Hence this case is a simplified version of the case below.
+ nscoord contentBSize = 0;
+ nscoord autoBSize = aReflowInput.ApplyMinMaxBSize(contentBSize);
+ aMetrics.mCarriedOutBEndMargin.Zero();
+ autoBSize += borderPadding.BStartEnd(wm);
+ finalSize.BSize(wm) = autoBSize;
+ }
else if (aState.mReflowStatus.IsComplete()) {
nscoord contentBSize = blockEndEdgeOfChildren - borderPadding.BStart(wm);
nscoord autoBSize = aReflowInput.ApplyMinMaxBSize(contentBSize);
if (autoBSize != contentBSize) {
// Our min- or max-bsize value made our bsize change. Don't carry out
// our kids' block-end margins.
aMetrics.mCarriedOutBEndMargin.Zero();
}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-block-001-ref.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Reftest Reference</title>
+ <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+ <style>
+ div {
+ border: 1em solid green;
+ }
+ .height-ref {
+ height: 50px;
+ background: lightblue;
+ }
+ .width-ref {
+ width: 50px;
+ background: lightblue;
+ }
+ .floatLBasic-ref {
+ float: left;
+ width: 0;
+ }
+ .floatLWidth-ref {
+ float: left;
+ width: 50px;
+ }
+ </style>
+</head>
+<body>
+ <div></div>
+ <br>
+
+ <div class="height-ref"></div>
+ <br>
+
+ <div class="height-ref"></div>
+ <br>
+
+ <div class="width-ref"></div>
+ <br>
+
+ <div class="width-ref"></div>
+ <br>
+
+ <div class="floatLBasic-ref"></div>
+ <br>
+
+ <div class="floatLWidth-ref"></div>
+ <br>
+
+ outside before<div></div>outside after
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-block-001.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: 'contain: size' on block elements should zero the height if unspecified, and should ensure baseline alignment consistency with empty (0x0) objects of the same type. If max-width is specified, 'contain: size' should constrain the block to the specified size.</title>
+ <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+ <link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
+ <link rel="match" href="contain-size-block-001-ref.html">
+ <style>
+ div {
+ contain: size;
+ border: 1em solid green;
+ background: red;
+ color:transparent;
+ }
+ .minHeight {
+ min-height: 50px;
+ background: lightblue;
+ }
+ .height {
+ height: 50px;
+ background: lightblue;
+ }
+ .maxWidth {
+ max-width: 50px;
+ background: lightblue;
+ }
+ .width {
+ width: 50px;
+ background: lightblue;
+ }
+ .floatLBasic {
+ float: left;
+ width: auto;
+ }
+ .floatLWidth {
+ float: left;
+ width: 50px;
+ }
+ </style>
+</head>
+<body>
+ <div>CSS Test: A size-contained block element with no specified size should render at 0 height regardless of content.</div>
+ <br>
+
+ <div class="minHeight">CSS Test: A size-contained block element with specified min-height should render at given min-height regardless of content.</div>
+ <br>
+
+ <div class="height">CSS Test: A size-contained block element with specified height should render at given height regardless of content.</div>
+ <br>
+
+ <div class="maxWidth">CSS Test: A size-contained block element with specified max-width should render at given max-width and zero height regardless of content.</div>
+ <br>
+
+ <div class="width">CSS Test: A size-contained block element with specified width should render at given width and zero height regardless of content.</div>
+ <br>
+
+ <div class="floatLBasic">CSS Test: A size-contained floated block element with auto width and no specified height should render at 0px by 0px regardless of content.</div>
+ <br>
+
+ <div class="floatLWidth">CSS Test: A size-contained floated block element with specified width and no specified height should render at given width and 0 height regardless of content.</div>
+ <br>
+
+ outside before<div>CSS Test: A size-contained block element should perform baseline alignment as if the container were empty.</div>outside after
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-inline-block-001-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Reftest Reference</title>
+ <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+ <style>
+ div {
+ display: inline-block;
+ border: 1em solid green;
+ }
+ .height-ref {
+ height: 50px;
+ }
+ .width-ref {
+ width: 50px;
+ }
+ </style>
+</head>
+<body>
+ <div></div>
+ <br>
+
+ outside before<div></div>outside after
+ <br>
+
+ <div class="height-ref"></div>
+ <br>
+
+ <div class="height-ref"></div>
+ <br>
+
+ <div class="width-ref"></div>
+ <br>
+
+ <div class="width-ref"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-inline-block-001.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: 'contain: size' on inline- elements should zero the height and/or width if unspecified, and should ensure baseline alignment consistency with empty (0x0) objects of the same type.</title>
+ <link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
+ <link rel="help" href="https://drafts.csswg.org/css-contain/#containment-size">
+ <link rel="match" href="contain-size-inline-block-001-ref.html">
+ <style>
+ div {
+ display: inline-block;
+ contain:size;
+ border: 1em solid green;
+ background: red;
+ color: transparent;
+ }
+ .minHeight {
+ min-height: 50px;
+ }
+ .height {
+ height: 50px;
+ }
+ .minWidth {
+ min-width: 50px;
+ }
+ .width {
+ width: 50px;
+ }
+ </style>
+</head>
+<body>
+ <div>CSS Test: A size-contained inline-block element with no specified size should render at 0 height and 0 width regardless of content.</div>
+ <br>
+
+ outside before<div>CSS Test: A size-contained inline-block element should perform baseline alignment as if the container were empty.</div>outside after
+ <br>
+
+ <div class="minHeight">CSS Test: A size-contained inline-block element with specified min-height should render at given min-height and 0 width regardless of content.</div>
+ <br>
+
+ <div class="height">CSS Test: A size-contained inline-block element with specified height should render at given height and 0 width regardless of content.</div>
+ <br>
+
+ <div class="minWidth">CSS Test: A size-contained inline-block element with specified min-width should render at given min-width and 0 height regardless of content.</div>
+ <br>
+
+ <div class="width">CSS Test: A size-contained inline-block element with specified width should render at given width and 0 height regardless of content.</div>
+</body>
+</html>
--- a/layout/reftests/w3c-css/submitted/contain/reftest.list
+++ b/layout/reftests/w3c-css/submitted/contain/reftest.list
@@ -8,8 +8,10 @@ default-preferences pref(layout.css.cont
pref(layout.css.overflow-clip-box.enabled,true) == contain-paint-clip-006.html contain-paint-clip-006-ref.html
== contain-paint-containing-block-absolute-001.html contain-paint-containing-block-absolute-001-ref.html
== contain-paint-containing-block-fixed-001.html contain-paint-containing-block-fixed-001-ref.html
== contain-paint-formatting-context-float-001.html contain-paint-formatting-context-float-001-ref.html
== contain-paint-formatting-context-margin-001.html contain-paint-formatting-context-margin-001-ref.html
== contain-paint-stacking-context-001a.html contain-paint-stacking-context-001-ref.html
== contain-paint-stacking-context-001b.html contain-paint-stacking-context-001-ref.html
== contain-size-button-001.html contain-size-button-001-ref.html
+== contain-size-block-001.html contain-size-block-001-ref.html
+== contain-size-inline-block-001.html contain-size-inline-block-001-ref.html