Bug 858332: Make flex items pseudo-stacking contexts, per recent spec change. r=mats
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 18 Apr 2013 09:51:18 -0700
changeset 129224 cf3a2de4af838b094dc79cabf0d4cb090c21934a
parent 129223 a520eb3b34ae63cde7a4ad99c3d9ed66257a5ff2
child 129225 cb02e3858e1ff76ad8ef0f09ff4ab4efdb7b5da0
push id24562
push userryanvm@gmail.com
push dateFri, 19 Apr 2013 01:24:04 +0000
treeherdermozilla-central@f8d27fe5d7c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs858332
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 858332: Make flex items pseudo-stacking contexts, per recent spec change. r=mats
layout/generic/nsFlexContainerFrame.cpp
layout/reftests/flexbox/flexbox-items-as-stacking-contexts-2-ref.html
layout/reftests/flexbox/flexbox-items-as-stacking-contexts-2.html
layout/reftests/flexbox/flexbox-items-as-stacking-contexts-3-ref.html
layout/reftests/flexbox/flexbox-items-as-stacking-contexts-3.html
layout/reftests/flexbox/reftest.list
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1056,17 +1056,17 @@ uint32_t
 GetDisplayFlagsForFlexItem(nsIFrame* aFrame)
 {
   MOZ_ASSERT(aFrame->IsFlexItem(), "Should only be called on flex items");
 
   const nsStylePosition* pos = aFrame->StylePosition();
   if (pos->mZIndex.GetUnit() == eStyleUnit_Integer) {
     return nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT;
   }
-  return 0;
+  return nsIFrame::DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT;
 }
 
 void
 nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                        const nsRect&           aDirtyRect,
                                        const nsDisplayListSet& aLists)
 {
   MOZ_ASSERT(nsLayoutUtils::IsFrameListSorted<IsOrderLEQWithDOMFallback>(mFrames),
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-items-as-stacking-contexts-2-ref.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <style>
+    body { font: 10px sans-serif }
+    .flexContainer {
+      background: orange;
+      width: 70px;
+      padding: 2px;
+      margin-bottom: 2px;
+    }
+
+    .flexContainer > div:first-child {
+      margin-right: 10px; /* the space between the flex items, in testcase */
+    }
+
+    .item1 {
+      display: inline-block;
+      background: lightblue;
+      width: 30px;
+    }
+    .item2 {
+      display: inline-block;
+      background: yellow;
+      width: 30px;
+    }
+  </style>
+</head>
+<body>
+  <div class="flexContainer"
+    ><div class="item1">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <div class="flexContainer"
+    ><div class="item1" style="position:relative">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <div class="flexContainer"
+    ><div class="item1" style="position:relative">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <div class="flexContainer"
+    ><div class="item2">HereIsSomeMoreLongText</div
+    ><div class="item1">ThisIsALongUnbrokenString</div
+  ></div>
+
+  <div class="flexContainer"
+    ><div class="item2">HereIsSomeMoreLongText</div
+    ><div class="item1">ThisIsALongUnbrokenString</div
+  ></div>
+
+  <div class="flexContainer"
+    ><div class="item2" style="position:relative">HereIsSomeMoreLongText</div
+    ><div class="item1">ThisIsALongUnbrokenString</div
+  ></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-items-as-stacking-contexts-2.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- This testcase checks flex items are painted atomically. In particular,
+     if one item has content that overflows into the region of another item,
+     then one item is painted "behind" the other; there shouldn't normally
+     any interleaving of backgrounds and content between the two items.
+
+     This testcase also tests some special cases that will change the paint
+     ordering - specifically, the properties "position", "z-index", and
+     "order" on flex items.
+ -->
+<html>
+<head>
+  <style>
+    body { font: 10px sans-serif }
+    .flexContainer {
+      background: orange;
+      display: flex;
+      justify-content: space-between;
+      width: 70px;
+      padding: 2px;
+      margin-bottom: 2px;
+    }
+    .item1 {
+      background: lightblue;
+      width: 30px;
+    }
+    .item2 {
+      background: yellow;
+      width: 30px;
+    }
+  </style>
+</head>
+<body>
+  <!-- This container has two flex items, the first of which has content
+       sticking out & overlapping the second.  If they're painting atomically
+       (and in the right order), the second item's background should cover the
+       first item's overflowing content. -->
+  <div class="flexContainer"
+    ><div class="item1">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <!-- Now, the first item is relatively positioned, which should make it paint
+       on top of everything. -->
+  <div class="flexContainer"
+    ><div class="item1" style="position:relative">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <!-- Now, the first item is has "z-index" set, which should make it paint on
+       top of everything. -->
+  <div class="flexContainer"
+    ><div class="item1" style="z-index: 1">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <!-- Now, the first item has "order" set to a higher value than default,
+       which should make it paint on top (and at the far right) -->
+  <div class="flexContainer"
+    ><div class="item1" style="order: 1">ThisIsALongUnbrokenString</div
+    ><div class="item2">HereIsSomeMoreLongText</div
+  ></div>
+
+  <!-- And for thoroughness, let's set "order" to a lower value than default,
+       on the second item. (Should render the same as previous example.)  -->
+  <div class="flexContainer"
+    ><div class="item1">ThisIsALongUnbrokenString</div
+    ><div class="item2" style="order: -1">HereIsSomeMoreLongText</div
+  ></div>
+
+  <!-- ...but if we relatively position that second item, it should paint
+       on top again, despite its low "order" value. -->
+  <div class="flexContainer"
+    ><div class="item1">ThisIsALongUnbrokenString</div
+    ><div class="item2" style="order: -1; position: relative">HereIsSomeMoreLongText</div
+  ></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-items-as-stacking-contexts-3-ref.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <style>
+    .flexContainer {
+      background: orange;
+      width: 70px;
+      height: 20px;
+      padding: 2px;
+      margin-bottom: 2px;
+    }
+    .item1 {
+      display: inline-block;
+      background: lightblue;
+      width: 30px;
+      height: 16px;
+      padding: 2px;
+      margin-right: 2px;
+      vertical-align: top;
+    }
+    .item2 {
+      display: inline-block;
+      background: yellow;
+      width: 30px;
+      height: 16px;
+      padding: 2px;
+      vertical-align: top;
+    }
+    .grandchildA {
+      background: purple;
+      width: 80px;
+      height: 6px;
+      position: relative;
+      z-index: 10;
+    }
+    .grandchildB {
+      background: teal;
+      width: 80px;
+      height: 6px;
+      position: relative;
+      z-index: 20;
+    }
+    .grandchildC {
+      background: lime;
+      width: 20px;
+      height: 16px;
+      position: relative;
+      /* This z-index should interleave this content
+         between grandchildA and grandchildB: */
+      z-index: 15;
+    }
+  </style>
+</head>
+<body>
+  <div class="flexContainer"
+    ><div class="item1"
+      ><div class="grandchildA"></div
+      ><div class="grandchildB"></div
+    ></div
+    ><div class="item2"
+      ><div class="grandchildC"></div
+    ></div
+  ></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-items-as-stacking-contexts-3.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- This testcase checks that flex items are painted as pseudo-stacking
+     contexts, instead of full stacking contexts. In other words, content
+     inside of one flex item should be able to iterleave between pieces of
+     content in another flex item, if we set appropriately interleaving
+     "z-index" values. -->
+<html>
+<head>
+  <style>
+    .flexContainer {
+      background: orange;
+      display: flex;
+      justify-content: space-between;
+      width: 70px;
+      height: 20px;
+      padding: 2px;
+      margin-bottom: 2px;
+    }
+    .item1 {
+      background: lightblue;
+      width: 30px;
+      padding: 2px;
+    }
+    .item2 {
+      background: yellow;
+      width: 30px;
+      padding: 2px;
+    }
+    .grandchildA {
+      background: purple;
+      width: 80px;
+      height: 6px;
+      position: relative;
+      z-index: 10;
+    }
+    .grandchildB {
+      background: teal;
+      width: 80px;
+      height: 6px;
+      position: relative;
+      z-index: 20;
+    }
+    .grandchildC {
+      background: lime;
+      width: 20px;
+      height: 16px;
+      position: relative;
+      /* This z-index should interleave this content
+         between grandchildA and grandchildB: */
+      z-index: 15;
+    }
+  </style>
+</head>
+<body>
+  <!-- This flex container's first flex item has content that overflows
+       and overlap the second flex item.  The z-index values are set such
+       that this content should interleave; grandchildC should
+       paint on top of grandchildA, but underneath grandchildB. -->
+  <div class="flexContainer"
+    ><div class="item1"
+      ><div class="grandchildA"></div
+      ><div class="grandchildB"></div
+    ></div
+    ><div class="item2"
+      ><div class="grandchildC"></div
+    ></div
+  ></div>
+</body>
+</html>
--- a/layout/reftests/flexbox/reftest.list
+++ b/layout/reftests/flexbox/reftest.list
@@ -121,18 +121,20 @@ fuzzy-if(d2d&&layersGPUAccelerated,24,14
 # Tests for handling of floated elements inside a flexbox
 == flexbox-float-1a.xhtml  flexbox-float-1-ref.xhtml
 == flexbox-float-1b.xhtml  flexbox-float-1-ref.xhtml
 == flexbox-float-1c.xhtml  flexbox-float-1-ref.xhtml
 == flexbox-float-1d.xhtml  flexbox-float-1-ref.xhtml
 == flexbox-float-2a.xhtml  flexbox-float-2-ref.xhtml
 == flexbox-float-2b.xhtml  flexbox-float-2-ref.xhtml
 
-# Tests for flex items as stacking contexts
+# Tests for flex items as (pseudo) stacking contexts
 == flexbox-items-as-stacking-contexts-1.xhtml flexbox-items-as-stacking-contexts-1-ref.xhtml
+== flexbox-items-as-stacking-contexts-2.html flexbox-items-as-stacking-contexts-2-ref.html
+== flexbox-items-as-stacking-contexts-3.html flexbox-items-as-stacking-contexts-3-ref.html
 
 # Tests for "min-width" and "min-height" on flex items.
 == flexbox-minSize-horiz-1.xhtml flexbox-minSize-horiz-1-ref.xhtml
 fails == flexbox-minSize-vert-1.xhtml  flexbox-minSize-vert-1-ref.xhtml # bug 852367
 
 # Tests for the order in which we paint flex items
 == flexbox-paint-ordering-1.xhtml flexbox-paint-ordering-1-ref.xhtml
 == flexbox-paint-ordering-2.xhtml flexbox-paint-ordering-2-ref.xhtml
@@ -156,18 +158,18 @@ fails == flexbox-minSize-vert-1.xhtml  f
 == flexbox-justify-content-horiz-5.xhtml flexbox-justify-content-horiz-5-ref.xhtml
 == flexbox-justify-content-vert-1.xhtml flexbox-justify-content-vert-1-ref.xhtml
 == flexbox-justify-content-vert-2.xhtml flexbox-justify-content-vert-2-ref.xhtml
 == flexbox-justify-content-vert-3.xhtml flexbox-justify-content-vert-3-ref.xhtml
 == flexbox-justify-content-vert-4.xhtml flexbox-justify-content-vert-4-ref.xhtml
 == flexbox-justify-content-vert-5.xhtml flexbox-justify-content-vert-5-ref.xhtml
 
 # Tests for inline content in a flexbox that gets wrapped in an anonymous block
-== flexbox-inlinecontent-horiz-1a.xhtml flexbox-inlinecontent-horiz-1-ref.xhtml
-== flexbox-inlinecontent-horiz-1b.xhtml flexbox-inlinecontent-horiz-1-ref.xhtml
+fails == flexbox-inlinecontent-horiz-1a.xhtml flexbox-inlinecontent-horiz-1-ref.xhtml # reference case rendering is incorrect; bug 858333
+fails == flexbox-inlinecontent-horiz-1b.xhtml flexbox-inlinecontent-horiz-1-ref.xhtml # reference case rendering is incorrect; bug 858333
 == flexbox-inlinecontent-horiz-2.xhtml  flexbox-inlinecontent-horiz-2-ref.xhtml
 == flexbox-inlinecontent-horiz-3a.xhtml flexbox-inlinecontent-horiz-3-ref.xhtml
 == flexbox-inlinecontent-horiz-3b.xhtml flexbox-inlinecontent-horiz-3-ref.xhtml
 == flexbox-inlinecontent-horiz-3c.xhtml flexbox-inlinecontent-horiz-3-ref.xhtml
 == flexbox-inlinecontent-horiz-4.xhtml  flexbox-inlinecontent-horiz-4-ref.xhtml
 == flexbox-inlinecontent-horiz-5.xhtml  flexbox-inlinecontent-horiz-5-ref.xhtml
 
 # Tests for intrinsic sizing of flexboxes