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

This commit is contained in:
Daniel Holbert 2012-11-30 00:13:23 -08:00
parent 95e4773bcc
commit 49e9f0770b
4 changed files with 170 additions and 1 deletions

View File

@ -8,6 +8,7 @@
/* rendering object for CSS "display: flex" */
#include "nsFlexContainerFrame.h"
#include "nsDisplayList.h"
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsStyleContext.h"
@ -980,8 +981,11 @@ nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
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);
}

View File

@ -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>

View File

@ -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>

View File

@ -100,6 +100,9 @@ test-pref(layout.css.flexbox.enabled,true) == flexbox-items-as-stacking-contexts
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