Bug 1467209 - Implement contain:size for blockFrame, add reftests.
MozReview-Commit-ID: 9lDZkAllu8I
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -470,27 +470,30 @@ nsBlockFrame::InvalidateFrameWithRect(co
return;
}
nsContainerFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey, aRebuildDisplayItems);
}
nscoord
nsBlockFrame::GetLogicalBaseline(WritingMode aWM) const
{
+ if (StyleDisplay()->IsContainSize()) {
+ return BSize(aWM);
+ }
auto lastBaseline =
BaselineBOffset(aWM, BaselineSharingGroup::eLast, AlignmentContext::eInline);
return BSize(aWM) - lastBaseline;
}
bool
nsBlockFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup,
nscoord* aBaseline) const
{
- if (aBaselineGroup == BaselineSharingGroup::eFirst) {
+ if (aBaselineGroup == BaselineSharingGroup::eFirst || StyleDisplay()->IsContainSize()) {
return nsLayoutUtils::GetFirstLineBaseline(aWM, this, aBaseline);
}
for (ConstReverseLineIterator line = LinesRBegin(), line_end = LinesREnd();
line != line_end; ++line) {
if (line->IsBlock()) {
nscoord offset;
nsIFrame* kid = line->mFirstChild;
@@ -696,16 +699,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 +792,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 +1631,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,69 @@
+<!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;
+ }
+ .iFlexBasic-ref {
+ vertical-align: top;
+ display: inline-flex;
+ width: 0;
+ }
+ .iFlexWidth-ref {
+ vertical-align: top;
+ display: inline-flex;
+ 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>
+
+ <div class="iFlexBasic-ref"></div>
+ <br>
+
+ <div class="iFlexWidth-ref"></div>
+ <br>
+
+ outside before<div></div>outside after
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-block-001.html
@@ -0,0 +1,79 @@
+<!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="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;
+ }
+ .iFlexBasic {
+ display: inline-flex;
+ width: auto;
+ }
+ .iFlexWidth {
+ display: inline-flex;
+ 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>
+
+ <div class="iFlexBasic">CSS Test: A size-contained inline-flex element with auto width and no specified height should render at 0px by 0px regardless of content.</div>
+ <br>
+
+ <div class="iFlexWidth">CSS Test: A size-contained inline-flex 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>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-inline-block-001-ref.html
@@ -0,0 +1,70 @@
+<!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;
+ }
+ .floatLBasic-ref {
+ float: left;
+ width: 0;
+ height: 0;
+ }
+ .floatLWidth-ref {
+ float: left;
+ width: 50px;
+ height: 0;
+ }
+ .iFlexBasic-ref {
+ display: inline-flex;
+ width: 0;
+ height: 0;
+ }
+ .iFlexWidth-ref {
+ display: inline-flex;
+ width: 50px;
+ height: 0;
+ }
+ </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>
+ <br>
+
+ <div class="floatLBasic-ref"></div>
+ <br>
+
+ <div class="floatLWidth-ref"></div>
+ <br>
+
+ <div class="iFlexBasic-ref"></div>
+ <br>
+
+ <div class="iFlexWidth-ref"></div>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-inline-block-001.html
@@ -0,0 +1,76 @@
+<!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="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;
+ }
+ .floatLBasic {
+ float: left;
+ width: auto;
+ }
+ .floatLWidth {
+ float: left;
+ width: 50px;
+ }
+ .iFlex{
+ display: inline-flex;
+ width: auto;
+ }
+ .iFlexWidth {
+ display: inline-flex;
+ 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>
+ <br>
+
+ <div class="floatLBasic">CSS Test: A size-contained floated inline-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 inline-block element with specified width and no specified height should render at given width and 0 height regardless of content.</div>
+ <br>
+
+ <div class="iFlexBasic">CSS Test: A size-contained inline-flex element with auto width and no specified height should render at 0px by 0px regardless of content.</div>
+ <br>
+
+ <div class="iFlexWidth">CSS Test: A size-contained inline-flex element with specified width and no specified height should render at given width and 0 height regardless of content.</div>
+</body>
+</html>
\ No newline at end of file
--- a/layout/reftests/w3c-css/submitted/contain/reftest.list
+++ b/layout/reftests/w3c-css/submitted/contain/reftest.list
@@ -7,9 +7,11 @@ default-preferences pref(layout.css.cont
== contain-paint-clip-005.html contain-paint-clip-003-ref.html
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-block-001.html contain-size-block-001-ref.html
+== contain-size-inline-block-001.html contain-size-inline-block-001-ref.html
== contain-size-button-001.html contain-size-button-001-ref.html
\ No newline at end of file