Bug 808767: Put flex items' borders & backgrounds into the BlockBorderBackgrounds display-list, so that overlapping flex items & their contents will paint in the right order. r=dbaron
authorDaniel Holbert <dholbert@cs.stanford.edu>
Fri, 30 Nov 2012 00:13:23 -0800
changeset 114583 34d5413b7ed94f4312657509429853d62bdcf896
parent 114582 1f2e0e82aa7df4db35c2add56fa88966423625e5
child 114584 6e341bb69bcf79ba90a29eb0af8b065caebe1cab
push id23926
push userryanvm@gmail.com
push dateSat, 01 Dec 2012 15:27:30 +0000
treeherdermozilla-central@ecdf0e332f17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs808767
milestone20.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 808767: Put flex items' borders & backgrounds into the BlockBorderBackgrounds display-list, so that overlapping flex items & their contents will paint in the right order. r=dbaron
layout/generic/nsFlexContainerFrame.cpp
layout/reftests/flexbox/flexbox-paint-ordering-1-ref.xhtml
layout/reftests/flexbox/flexbox-paint-ordering-1.xhtml
layout/reftests/flexbox/reftest.list
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -3,16 +3,17 @@
 
 /* This Source Code is subject to the terms of the Mozilla Public License
  * version 2.0 (the "License"). You can obtain a copy of the License at
  * http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS "display: flex" */
 
 #include "nsFlexContainerFrame.h"
+#include "nsDisplayList.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "prlog.h"
 
 using namespace mozilla::css;
 
 #ifdef PR_LOGGING
@@ -975,18 +976,21 @@ GetDisplayFlagsForFlexItem(nsIFrame* aFr
 NS_IMETHODIMP
 nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                        const nsRect&           aDirtyRect,
                                        const nsDisplayListSet& aLists)
 {
   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Our children are all block-level, so their borders/backgrounds all go on
+  // the BlockBorderBackgrounds list.
+  nsDisplayListSet childLists(aLists, aLists.BlockBorderBackgrounds());
   for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
-    rv = BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists,
+    rv = BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, childLists,
                                   GetDisplayFlagsForFlexItem(e.get()));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 #ifdef DEBUG
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-paint-ordering-1-ref.xhtml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <style>
+      .container {
+        width: 40px;
+        height: 14px;
+        border: 2px solid green;
+        margin-bottom: 2px;
+      }
+      .a {
+          width: 16px;
+          height: 10px;
+          background: blue;
+          min-width: 0;
+          border: 2px solid lightblue;
+      }
+      .b {
+          width: 16px;
+          height: 10px;
+          background: purple;
+          min-width: 0;
+          border: 2px solid slateblue;
+      }
+      .aKid {
+          margin-left: 10px;
+          margin-top: 2px;
+          width: 16px;
+          height: 6px;
+          background: yellow;
+          border: 1px solid black;
+      }
+      .a, .b { float: left; }
+    </style>
+  </head>
+  <body>
+    <!-- Just 6 copies of the same container, since they all should look the
+         same (except for the final "position: fixed" one, which needs to be
+         explicitly marked as "position: fixed" or else it paints differently
+         on Android.) -->
+    <div class="container">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <div class="container">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <div class="container">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <div class="container">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <div class="container">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <div class="container" style="position: fixed">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-paint-ordering-1.xhtml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!-- Testcase with flex items containing overlapping content, to test
+     their paint-order. -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <style>
+      body {
+        line-height: 0;
+      }
+      .container {
+        width: 40px;
+        height: 14px;
+        border: 2px solid green;
+        margin-bottom: 2px;
+      }
+      .a {
+          width: 16px;
+          height: 10px;
+          background: blue;
+          min-width: 0;
+          border: 2px solid lightblue;
+      }
+      .b {
+          width: 16px;
+          height: 10px;
+          background: purple;
+          min-width: 0;
+          border: 2px solid slateblue;
+      }
+      .aKid {
+          margin-left: 10px;
+          margin-top: 2px;
+          width: 16px;
+          height: 6px;
+          background: yellow;
+          border: 1px solid black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- inline-level flex container -->
+    <div class="container" style="display: inline-flex">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <!-- block-level flex container -->
+    <div class="container" style="display: flex">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <!-- floated flex container -->
+    <div class="container" style="display: flex; float: left">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+    <!-- Helper-div to clear floats: -->
+    <div style="clear: both"/>
+
+    <!-- relatively-positioned flex container -->
+    <div class="container" style="display: flex; position: relative">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+    <!-- absolutely-positioned flex container -->
+    <div class="container" style="display: flex; position: absolute">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+    <!--- Spacer div, since abspos div doesn't set aside space for itself -->
+    <div style="height: 20px"/>
+
+    <!-- fixed-position flex container -->
+    <div class="container" style="display: flex; position: fixed">
+      <div class="a"><div class="aKid"/></div>
+      <div class="b"></div>
+    </div>
+
+  </body>
+</html>
--- a/layout/reftests/flexbox/reftest.list
+++ b/layout/reftests/flexbox/reftest.list
@@ -95,16 +95,19 @@ test-pref(layout.css.flexbox.enabled,tru
 
 # Tests for flex items as stacking contexts
 test-pref(layout.css.flexbox.enabled,true) == flexbox-items-as-stacking-contexts-1.xhtml flexbox-items-as-stacking-contexts-1-ref.xhtml
 
 # Tests for (default) "min-width: auto" / "min-height: auto" in flex containers
 test-pref(layout.css.flexbox.enabled,true) == flexbox-minSize-horiz-1.xhtml flexbox-minSize-horiz-1-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-minSize-vert-1.xhtml  flexbox-minSize-vert-1-ref.xhtml
 
+# Tests for the order in which we paint flex items
+test-pref(layout.css.flexbox.enabled,true) == flexbox-paint-ordering-1.xhtml flexbox-paint-ordering-1-ref.xhtml
+
 # Tests for handling of absolutely/fixed/relatively-positioned flex items.
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-absolute-1.xhtml  flexbox-position-absolute-1-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-absolute-2.xhtml  flexbox-position-absolute-2-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-absolute-3.xhtml  flexbox-position-absolute-3-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-absolute-4.xhtml  flexbox-position-absolute-4-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-fixed-3.xhtml     flexbox-position-fixed-3-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-fixed-1.xhtml     flexbox-position-fixed-1-ref.xhtml
 test-pref(layout.css.flexbox.enabled,true) == flexbox-position-fixed-2.xhtml     flexbox-position-fixed-2-ref.xhtml