Bug 1467209 - Implement contain:size for HTMLButtonControlFrame.
MozReview-Commit-ID: Cwfni9ieX74
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -141,36 +141,40 @@ nsHTMLButtonControlFrame::BuildDisplayLi
DisplaySelectionOverlay(aBuilder, aLists.Content());
}
nscoord
nsHTMLButtonControlFrame::GetMinISize(gfxContext* aRenderingContext)
{
nscoord result;
DISPLAY_MIN_WIDTH(this, result);
-
- nsIFrame* kid = mFrames.FirstChild();
- result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
- kid,
- nsLayoutUtils::MIN_ISIZE);
-
+ if (StyleDisplay()->IsContainSize()) {
+ result = 0;
+ } else {
+ nsIFrame* kid = mFrames.FirstChild();
+ result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
+ kid,
+ nsLayoutUtils::MIN_ISIZE);
+ }
return result;
}
nscoord
nsHTMLButtonControlFrame::GetPrefISize(gfxContext* aRenderingContext)
{
nscoord result;
DISPLAY_PREF_WIDTH(this, result);
-
- nsIFrame* kid = mFrames.FirstChild();
- result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
- kid,
- nsLayoutUtils::PREF_ISIZE);
-
+ if (StyleDisplay()->IsContainSize()) {
+ result = 0;
+ } else {
+ nsIFrame* kid = mFrames.FirstChild();
+ result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
+ kid,
+ nsLayoutUtils::PREF_ISIZE);
+ }
return result;
}
void
nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus)
@@ -256,16 +260,21 @@ nsHTMLButtonControlFrame::ReflowButtonCo
"We gave button-contents frame unconstrained available height, "
"so it should be complete");
// Compute the button's content-box size:
LogicalSize buttonContentBox(wm);
if (aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
// Button has a fixed block-size -- that's its content-box bSize.
buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedBSize();
+ } else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) {
+ // Button is intrinsically sized and has size containment.
+ // It should have a BSize that is either zero or the minimum
+ // specified BSize.
+ buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedMinBSize();
} else {
// Button is intrinsically sized -- it should shrinkwrap the
// button-contents' bSize:
buttonContentBox.BSize(wm) = contentsDesiredSize.BSize(wm);
// Make sure we obey min/max-bSize in the case when we're doing intrinsic
// sizing (we get it for free when we have a non-intrinsic
// aButtonReflowInput.ComputedBSize()). Note that we do this before
@@ -273,16 +282,18 @@ nsHTMLButtonControlFrame::ReflowButtonCo
// mComputedMinBSize are content bSizes.
buttonContentBox.BSize(wm) =
NS_CSS_MINMAX(buttonContentBox.BSize(wm),
aButtonReflowInput.ComputedMinBSize(),
aButtonReflowInput.ComputedMaxBSize());
}
if (aButtonReflowInput.ComputedISize() != NS_INTRINSICSIZE) {
buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedISize();
+ } else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) {
+ buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedMinISize();
} else {
buttonContentBox.ISize(wm) = contentsDesiredSize.ISize(wm);
buttonContentBox.ISize(wm) =
NS_CSS_MINMAX(buttonContentBox.ISize(wm),
aButtonReflowInput.ComputedMinISize(),
aButtonReflowInput.ComputedMaxISize());
}
@@ -317,17 +328,19 @@ nsHTMLButtonControlFrame::ReflowButtonCo
aButtonDesiredSize.SetSize(wm,
LogicalSize(wm, aButtonReflowInput.ComputedISize() + clbp.IStartEnd(wm),
buttonContentBox.BSize(wm) + clbp.BStartEnd(wm)));
// * Button's ascent is its child's ascent, plus the child's block-offset
// within our frame... unless it's orthogonal, in which case we'll use the
// contents inline-size as an approximation for now.
// XXX is there a better strategy? should we include border-padding?
- if (aButtonDesiredSize.GetWritingMode().IsOrthogonalTo(wm)) {
+ if (aButtonReflowInput.mStyleDisplay->IsContainSize()) {
+ aButtonDesiredSize.SetBlockStartAscent(childPos.B(wm));
+ } else if (aButtonDesiredSize.GetWritingMode().IsOrthogonalTo(wm)) {
aButtonDesiredSize.SetBlockStartAscent(contentsDesiredSize.ISize(wm));
} else {
aButtonDesiredSize.SetBlockStartAscent(contentsDesiredSize.BlockStartAscent() +
childPos.B(wm));
}
aButtonDesiredSize.SetOverflowAreasToDesiredBounds();
}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-button-001-ref.html
@@ -0,0 +1,62 @@
+<!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>
+ button {
+ border: 1em solid green;
+ }
+ .width-ref {
+ width: 50px;
+ }
+ .floatLBasic-ref {
+ float: left;
+ }
+ .floatLWidth-ref {
+ float: left;
+ width: 50px;
+ height: 0;
+ }
+ .iFlexBasic-ref {
+ display: inline-flex;
+ }
+ .iFlexWidth-ref {
+ display: inline-flex;
+ width: 50px;
+ height: 0;
+ }
+ .orthog-ref {
+ writing-mode: vertical-lr;
+ }
+ </style>
+</head>
+<body>
+ <button></button>
+ <br>
+
+ <button class="floatLBasic-ref"></button>
+ <br>
+
+ <button class="floatLWidth-ref"></button>
+ <br>
+
+ <button class="iFlexBasic-ref"></button>
+ <br>
+
+ <button class="iFlexWidth-ref"></button>
+ <br>
+
+ outside before<button></button>outside after
+ <br>
+
+ <button class="width-ref"></button>
+ <br>
+
+ <button class="width-ref"></button>
+ <br>
+
+ s<button class="orthog-ref"></button>endtext
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-size-button-001.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: 'contain: size' on buttons 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-button-001-ref.html">
+ <style>
+ button {
+ contain: size;
+ border: 1em solid green;
+ background: red;
+ color: transparent;
+ }
+ .minWidth {
+ min-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;
+ }
+ .orthog {
+ writing-mode: vertical-lr;
+ }
+ </style>
+</head>
+<body>
+ <button>CSS Test: A size-contained button with no specified size should render at 0 height regardless of content.</button>
+ <br>
+
+ <button class="floatLBasic">CSS Test: A size-contained floated button with auto width and no specified height should render at 0px by 0px regardless of content.</button>
+ <br>
+
+ <button class="floatLWidth">CSS Test: A size-contained floated button with specified width and no specified height should render at given width and 0 height regardless of content.</button>
+ <br>
+
+ <button class="iFlexBasic">CSS Test: A size-contained inline-flex button with auto width and no specified height should render at 0px by 0px regardless of content.</button>
+ <br>
+
+ <button class="iFlexWidth">CSS Test: A size-contained inline-flex button with specified width and no specified height should render at given width and 0 height regardless of content.</button>
+ <br>
+
+ outside before<button>CSS Test: A size-contained button should perform baseline alignment as if the container were empty.</button>outside after
+ <br>
+
+ <button class="minWidth">CSS Test: A size-contained button with specified min-width should render at given min-width and zero height regardless of content.</button>
+ <br>
+
+ <button class="width">CSS Test: A size-contained button with specified width should render at given width and zero height regardless of content.</button>
+ <br>
+
+ s<button class="orthog">CSS Test: A size-contained button with vertical text should perform baseline alignment as if the container were empty.</button>endtext
+</body>
+</html>
--- a/layout/reftests/w3c-css/submitted/contain/reftest.list
+++ b/layout/reftests/w3c-css/submitted/contain/reftest.list
@@ -7,8 +7,9 @@ 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-button-001.html contain-size-button-001-ref.html