Bug 862947: Use cb height instead of width for vertical margins & padding on flex items, even when they're a reflow root (e.g. for measuring reflow states). r=mats
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 23 Apr 2013 09:01:34 -0700
changeset 140592 4c26b1674a6e7d15c916d807d441b31d0b80d73b
parent 140591 34d00e20ff2da3d871f9c380f77fb9389521831d
child 140593 25d6b99f826f3aeb81a6e4bc6de3571f3dd28c3c
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs862947
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 862947: Use cb height instead of width for vertical margins & padding on flex items, even when they're a reflow root (e.g. for measuring reflow states). r=mats
layout/generic/crashtests/862947-1.html
layout/generic/crashtests/crashtests.list
layout/generic/nsHTMLReflowState.cpp
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/862947-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+
+div { display: flex; }
+div:after { display: -moz-deck; content: counter(b); }
+
+</style>
+</head>
+<body>
+
+<div></div>
+
+</body>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -454,8 +454,9 @@ load 842132-1.html
 test-pref(layout.css.flexbox.enabled,true) load 844529-1.html
 load 847130.xhtml
 load 847208.html
 asserts(4) load 847209.html # bug 847368
 test-pref(layout.css.flexbox.enabled,true) load 847211-1.html
 load 849603.html
 test-pref(layout.css.flexbox.enabled,true) load 851396-1.html
 test-pref(layout.css.flexbox.enabled,true) load 854263-1.html
+test-pref(layout.css.flexbox.enabled,true) load 862947-1.html
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1788,44 +1788,59 @@ GetFlexContainer(nsIFrame* aFrame)
       parent->GetType() != nsGkAtoms::flexContainerFrame) {
     return nullptr;
   }
 
   return static_cast<nsFlexContainerFrame*>(parent);
 }
 #endif // MOZ_FLEXBOX
 
+// Flex items resolve percentage margin & padding against the flex
+// container's height (which is the containing block height).
+// For everything else: the CSS21 spec requires that margin and padding
+// percentage values are calculated with respect to the *width* of the
+// containing block, even for margin & padding in the vertical axis.
+static nscoord
+VerticalOffsetPercentBasis(const nsIFrame* aFrame,
+                           nscoord aContainingBlockWidth,
+                           nscoord aContainingBlockHeight)
+{
+  if (!aFrame->IsFlexItem()) {
+    return aContainingBlockWidth;
+  }
+
+  if (aContainingBlockHeight == NS_AUTOHEIGHT) {
+    return 0;
+  }
+
+  return aContainingBlockHeight;
+}
+
 // XXX refactor this code to have methods for each set of properties
 // we are computing: width,height,line-height; margin; offsets
 
 void
 nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
                                    nscoord         aContainingBlockWidth,
                                    nscoord         aContainingBlockHeight,
                                    const nsMargin* aBorder,
                                    const nsMargin* aPadding,
                                    nsIAtom* aFrameType)
 {
   DISPLAY_INIT_CONSTRAINTS(frame, this,
                            aContainingBlockWidth, aContainingBlockHeight,
                            aBorder, aPadding);
 
-  // If this is the root frame, then set the computed width and
+  // If this is a reflow root, then set the computed width and
   // height equal to the available space
   if (nullptr == parentReflowState) {
-    MOZ_ASSERT(!frame->IsFlexItem(),
-               "the root frame can't be a flex item, since being a flex item "
-               "requires that you have a parent");
-    // Note that we pass the containing block width as the percent basis for
-    // both horizontal *and* vertical margins & padding, in our InitOffsets
-    // call here. This is correct per CSS 2.1; it'd be incorrect for e.g. flex
-    // items and grid items, but the root frame can't be either of those.
     // XXXldb This doesn't mean what it used to!
     InitOffsets(aContainingBlockWidth,
-                aContainingBlockWidth,
+                VerticalOffsetPercentBasis(frame, aContainingBlockWidth,
+                                           aContainingBlockHeight),
                 aFrameType, aBorder, aPadding);
     // Override mComputedMargin since reflow roots start from the
     // frame's boundary, which is inside the margin.
     mComputedMargin.SizeTo(0, 0, 0, 0);
     mComputedOffsets.SizeTo(0, 0, 0, 0);
 
     mComputedWidth = availableWidth - mComputedBorderPadding.LeftRight();
     if (mComputedWidth < 0)
@@ -1863,29 +1878,21 @@ nsHTMLReflowState::InitConstraints(nsPre
         fType = cbrs->frame->GetType();
         if (IS_TABLE_CELL(fType)) {
           // use the cell's computed height 
           aContainingBlockHeight = cbrs->mComputedHeight;
         }
       }
     }
 
-    // Flex containers resolve percentage margin & padding against the flex
-    // container's height (which is the containing block height).
-    // For everything else: the CSS21 spec requires that margin and padding
-    // percentage values are calculated with respect to the *width* of the
-    // containing block, even for margin & padding in the vertical axis.
     // XXX Might need to also pass the CB height (not width) for page boxes,
     // too, if we implement them.
-    nscoord verticalPercentBasis = aContainingBlockWidth;
-    if (frame->IsFlexItem()) {
-      verticalPercentBasis =
-        aContainingBlockHeight == NS_AUTOHEIGHT ? 0 : aContainingBlockHeight;
-    }
-    InitOffsets(aContainingBlockWidth, verticalPercentBasis,
+    InitOffsets(aContainingBlockWidth,
+                VerticalOffsetPercentBasis(frame, aContainingBlockWidth,
+                                           aContainingBlockHeight),
                 aFrameType, aBorder, aPadding);
 
     const nsStyleCoord &height = mStylePosition->mHeight;
     nsStyleUnit heightUnit = height.GetUnit();
 
     // Check for a percentage based height and a containing block height
     // that depends on the content height
     // XXX twiddling heightUnit doesn't help anymore