Bug 1398483 - Implement column and row gap for flexbox. r=dholbert

MozReview-Commit-ID: 2EmaG3G0HRI

--HG--
extra : rebase_source : ce90f9a38c0f3a6634a95b0f4f97a2a3fbd48a57
This commit is contained in:
Mihir Iyer 2018-06-19 10:28:31 -07:00
Родитель 61dd076163
Коммит b3ebeebc31
7 изменённых файлов: 433 добавлений и 25 удалений

Просмотреть файл

@ -887,17 +887,23 @@ protected:
class nsFlexContainerFrame::FlexLine : public LinkedListElement<FlexLine>
{
public:
FlexLine()
explicit FlexLine(nscoord aMainGapSize)
: mNumItems(0),
mNumFrozenItems(0),
mTotalItemMBP(0),
mTotalOuterHypotheticalMainSize(0),
mLineCrossSize(0),
mFirstBaselineOffset(nscoord_MIN),
mLastBaselineOffset(nscoord_MIN)
mLastBaselineOffset(nscoord_MIN),
mMainGapSize(aMainGapSize)
{}
// Returns the sum of our FlexItems' outer hypothetical main sizes.
nscoord GetSumOfGaps() const {
return mNumItems > 0 ? (mNumItems - 1) * mMainGapSize : 0;
}
// Returns the sum of our FlexItems' outer hypothetical main sizes plus the
// sum of main axis {row,column}-gaps between items.
// ("outer" = margin-box, and "hypothetical" = before flexing)
nscoord GetTotalOuterHypotheticalMainSize() const {
return mTotalOuterHypotheticalMainSize;
@ -983,7 +989,15 @@ public:
mTotalItemMBP = AddChecked(mTotalItemMBP, itemMBP);
mTotalOuterHypotheticalMainSize =
AddChecked(mTotalOuterHypotheticalMainSize, aItemOuterHypotheticalMainSize);
AddChecked(mTotalOuterHypotheticalMainSize,
aItemOuterHypotheticalMainSize);
// If the item added was not the first item in the line, we add in any gap
// space as needed.
if (mNumItems >= 2) {
mTotalOuterHypotheticalMainSize =
AddChecked(mTotalOuterHypotheticalMainSize, mMainGapSize);
}
}
// Computes the cross-size and baseline position of this FlexLine, based on
@ -1027,6 +1041,22 @@ public:
return mLastBaselineOffset;
}
/**
* Returns the number of items held in this line. Used for total gap
* calculations.
*/
uint32_t GetNumItems() const {
return mNumItems;
}
/**
* Returns the gap size in the main axis for this line. Used for gap
* calculations.
*/
nscoord GetMainGapSize() const {
return mMainGapSize;
}
// Runs the "Resolving Flexible Lengths" algorithm from section 9.7 of the
// CSS flexbox spec to distribute aFlexContainerMainSize among our flex items.
void ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
@ -1064,14 +1094,18 @@ private:
// Sum of margin/border/padding for the FlexItems in this FlexLine.
nscoord mTotalItemMBP;
// Sum of FlexItems' outer hypothetical main sizes.
// Sum of FlexItems' outer hypothetical main sizes and all main-axis
// {row,columnm}-gaps between items.
// (i.e. their flex base sizes, clamped via their min/max-size properties,
// plus their main-axis margin/border/padding.)
// plus their main-axis margin/border/padding, plus the sum of the gaps.)
nscoord mTotalOuterHypotheticalMainSize;
nscoord mLineCrossSize;
nscoord mFirstBaselineOffset;
nscoord mLastBaselineOffset;
// Maintain size of each {row,column}-gap in the main axis
const nscoord mMainGapSize;
};
// Information about a strut left behind by a FlexItem that's been collapsed
@ -2232,6 +2266,9 @@ public:
"miscounted the number of auto margins");
}
// Advances past the gap space (if any) between two flex items
void TraverseGap(nscoord aGapSize) { mPosition += aGapSize; }
// Advances past the packing space (if any) between two flex items
void TraversePackingSpace();
@ -2257,7 +2294,11 @@ public:
const ReflowInput& aReflowInput,
nscoord aContentBoxCrossSize,
bool aIsCrossSizeDefinite,
const FlexboxAxisTracker& aAxisTracker);
const FlexboxAxisTracker& aAxisTracker,
const nscoord aCrossGapSize);
// Advances past the gap (if any) between two flex lines
void TraverseGap() { mPosition += mCrossGapSize; }
// Advances past the packing space (if any) between two flex lines
void TraversePackingSpace();
@ -2279,6 +2320,8 @@ private:
uint32_t mNumPackingSpacesRemaining;
// XXX this should be uint16_t when we add explicit fallback handling
uint8_t mAlignContent;
nscoord mCrossGapSize = 0;
};
// Utility class for managing our position along the cross axis, *within* a
@ -2559,11 +2602,11 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
MOZ_ASSERT(!IsEmpty() || aLineInfo,
"empty lines should take the early-return above");
// Subtract space occupied by our items' margins/borders/padding, so we can
// just be dealing with the space available for our flex items' content
// Subtract space occupied by our items' margins/borders/padding/gaps, so
// we can just be dealing with the space available for our flex items' content
// boxes.
nscoord spaceAvailableForFlexItemsContentBoxes =
aFlexContainerMainSize - mTotalItemMBP;
aFlexContainerMainSize - (mTotalItemMBP + GetSumOfGaps());
nscoord origAvailableFreeSpace;
bool isOrigAvailFreeSpaceInitialized = false;
@ -2900,6 +2943,9 @@ MainAxisPositionTracker::
mNumAutoMarginsInMainAxis += item->GetNumAutoMarginsInAxis(mAxis);
}
// Subtract space required for row/col gap from the remaining packing space
mPackingSpaceRemaining -= aLine->GetSumOfGaps();
if (mPackingSpaceRemaining <= 0) {
// No available packing space to use for resolving auto margins.
mNumAutoMarginsInMainAxis = 0;
@ -3047,12 +3093,14 @@ CrossAxisPositionTracker::
const ReflowInput& aReflowInput,
nscoord aContentBoxCrossSize,
bool aIsCrossSizeDefinite,
const FlexboxAxisTracker& aAxisTracker)
const FlexboxAxisTracker& aAxisTracker,
const nscoord aCrossGapSize)
: PositionTracker(aAxisTracker.GetCrossAxis(),
aAxisTracker.IsCrossAxisReversed()),
mPackingSpaceRemaining(0),
mNumPackingSpacesRemaining(0),
mAlignContent(aReflowInput.mStylePosition->mAlignContent)
mAlignContent(aReflowInput.mStylePosition->mAlignContent),
mCrossGapSize(aCrossGapSize)
{
MOZ_ASSERT(aFirstLine, "null first line pointer");
@ -3105,6 +3153,11 @@ CrossAxisPositionTracker::
numLines++;
}
// Subtract space required for row/col gap from the remaining packing space
MOZ_ASSERT(numLines >= 1,
"GenerateFlexLines should've produced at least 1 line");
mPackingSpaceRemaining -= aCrossGapSize * (numLines - 1);
// If packing space is negative, 'space-between' and 'stretch' behave like
// 'flex-start', and 'space-around' and 'space-evenly' behave like 'center'.
// In those cases, it's simplest to just pretend we have a different
@ -3709,9 +3762,10 @@ FlexboxAxisTracker::InitAxesFromModernProps(
// back depending on aShouldInsertAtFront), and returns a pointer to it.
static FlexLine*
AddNewFlexLineToList(LinkedList<FlexLine>& aLines,
bool aShouldInsertAtFront)
bool aShouldInsertAtFront,
nscoord aMainGapSize)
{
FlexLine* newLine = new FlexLine();
FlexLine* newLine = new FlexLine(aMainGapSize);
if (aShouldInsertAtFront) {
aLines.insertFront(newLine);
} else {
@ -3761,6 +3815,7 @@ nsFlexContainerFrame::GenerateFlexLines(
nscoord aAvailableBSizeForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nscoord aMainGapSize,
nsTArray<nsIFrame*>& aPlaceholders, /* out */
LinkedList<FlexLine>& aLines /* out */)
{
@ -3779,7 +3834,8 @@ nsFlexContainerFrame::GenerateFlexLines(
// We have at least one FlexLine. Even an empty flex container has a single
// (empty) flex line.
FlexLine* curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront);
FlexLine* curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront,
aMainGapSize);
nscoord wrapThreshold;
if (isSingleLine) {
@ -3843,7 +3899,7 @@ nsFlexContainerFrame::GenerateFlexLines(
// Honor "page-break-before", if we're multi-line and this line isn't empty:
if (!isSingleLine && !curLine->IsEmpty() &&
childFrame->StyleDisplay()->mBreakBefore) {
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront);
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, aMainGapSize);
}
UniquePtr<FlexItem> item;
@ -3883,21 +3939,25 @@ nsFlexContainerFrame::GenerateFlexLines(
nscoord newOuterSize =
AddChecked(curLine->GetTotalOuterHypotheticalMainSize(),
itemOuterHypotheticalMainSize);
// Account for gap between this line's previous item and this item
newOuterSize = AddChecked(newOuterSize, aMainGapSize);
if (newOuterSize == nscoord_MAX || newOuterSize > wrapThreshold) {
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront);
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront,
aMainGapSize);
}
}
// Add item to current flex line (and update the line's bookkeeping about
// how large its items collectively are).
curLine->AddItem(item.release(), shouldInsertAtFront,
curLine->AddItem(item.release(),
shouldInsertAtFront,
itemInnerHypotheticalMainSize,
itemOuterHypotheticalMainSize);
// Honor "page-break-after", if we're multi-line and have more children:
if (!isSingleLine && childFrame->GetNextSibling() &&
childFrame->StyleDisplay()->mBreakAfter) {
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront);
curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, aMainGapSize);
}
itemIdxInContainer++;
}
@ -4089,6 +4149,9 @@ FlexLine::PositionItemsInMainAxis(uint8_t aJustifyContent,
mainAxisPosnTracker.ExitChildFrame(itemMainBorderBoxSize);
mainAxisPosnTracker.ExitMargin(item->GetMargin());
mainAxisPosnTracker.TraversePackingSpace();
if (item->getNext()) {
mainAxisPosnTracker.TraverseGap(mMainGapSize);
}
}
}
@ -4270,18 +4333,38 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
nscoord contentBoxMainSize = GetMainSizeFromReflowInput(aReflowInput,
axisTracker);
// Calculate gap size for main and cross axis
nscoord mainGapSize;
nscoord crossGapSize;
if (axisTracker.IsRowOriented()) {
mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap,
contentBoxMainSize);
crossGapSize =
nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap,
GetEffectiveComputedBSize(aReflowInput));
} else {
mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap,
contentBoxMainSize);
NS_WARNING_ASSERTION(aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE,
"Unconstrained inline size; this should only result "
"from huge sizes (not intrinsic sizing w/ orthogonal "
"flows)");
crossGapSize =
nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap,
aReflowInput.ComputedISize());
}
AutoTArray<StrutInfo, 1> struts;
DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus,
contentBoxMainSize, availableBSizeForContent,
struts, axisTracker);
struts, axisTracker, mainGapSize, crossGapSize);
if (!struts.IsEmpty()) {
// We're restarting flex layout, with new knowledge of collapsed items.
aStatus.Reset();
DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus,
contentBoxMainSize, availableBSizeForContent,
struts, axisTracker);
struts, axisTracker, mainGapSize, crossGapSize);
}
}
@ -4515,7 +4598,9 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
nscoord aContentBoxMainSize,
nscoord aAvailableBSizeForContent,
nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker)
const FlexboxAxisTracker& aAxisTracker,
nscoord aMainGapSize,
nscoord aCrossGapSize)
{
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
@ -4527,6 +4612,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
aContentBoxMainSize,
aAvailableBSizeForContent,
aStruts, aAxisTracker,
aMainGapSize,
placeholderKids, lines);
if (lines.getFirst()->IsEmpty() &&
@ -4679,7 +4765,8 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
CrossAxisPositionTracker
crossAxisPosnTracker(lines.getFirst(),
aReflowInput, contentBoxCrossSize,
isCrossSizeDefinite, aAxisTracker);
isCrossSizeDefinite, aAxisTracker,
aCrossGapSize);
// Now that we know the cross size of each line (including
// "align-content:stretch" adjustments, from the CrossAxisPositionTracker
@ -4717,6 +4804,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
ConvertLegacyStyleToJustifyContent(StyleXUL()) :
aReflowInput.mStylePosition->mJustifyContent;
lineIndex = 0;
for (FlexLine* line = lines.getFirst(); line; line = line->getNext(),
++lineIndex) {
@ -4738,6 +4826,10 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
aAxisTracker);
crossAxisPosnTracker.TraverseLine(*line);
crossAxisPosnTracker.TraversePackingSpace();
if (line->getNext()) {
crossAxisPosnTracker.TraverseGap();
}
}
// If the container should derive its baseline from the last FlexLine,
@ -5145,9 +5237,22 @@ nsFlexContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
const nsStylePosition* stylePos = StylePosition();
const FlexboxAxisTracker axisTracker(this, GetWritingMode());
nscoord mainGapSize;
if (axisTracker.IsRowOriented()) {
mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap,
NS_UNCONSTRAINEDSIZE);
} else {
mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap,
NS_UNCONSTRAINEDSIZE);
}
const bool useMozBoxCollapseBehavior =
ShouldUseMozBoxCollapseBehavior(StyleDisplay());
// The loop below sets aside space for a gap before each item besides the
// first. This bool helps us handle that special-case.
bool onFirstChild = true;
for (nsIFrame* childFrame : mFrames) {
// If we're using legacy "visibility:collapse" behavior, then we don't
// care about the sizes of any collapsed children.
@ -5158,7 +5263,8 @@ nsFlexContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
aType);
// * For a row-oriented single-line flex container, the intrinsic
// {min/pref}-isize is the sum of its items' {min/pref}-isizes.
// {min/pref}-isize is the sum of its items' {min/pref}-isizes and
// (n-1) column gaps.
// * For a column-oriented flex container, the intrinsic min isize
// is the max of its items' min isizes.
// * For a row-oriented multi-line flex container, the intrinsic
@ -5167,6 +5273,10 @@ nsFlexContainerFrame::IntrinsicISize(gfxContext* aRenderingContext,
if (axisTracker.IsRowOriented() &&
(isSingleLine || aType == nsLayoutUtils::PREF_ISIZE)) {
containerISize += childISize;
if (!onFirstChild) {
containerISize += mainGapSize;
}
onFirstChild = false;
} else { // (col-oriented, or MIN_ISIZE for multi-line row flex container)
containerISize = std::max(containerISize, childISize);
}

Просмотреть файл

@ -258,7 +258,9 @@ protected:
nscoord aContentBoxMainSize,
nscoord aAvailableBSizeForContent,
nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker);
const FlexboxAxisTracker& aAxisTracker,
nscoord aMainGapSize,
nscoord aCrossGapSize);
/**
* Checks whether our child-frame list "mFrames" is sorted, using the given
@ -353,6 +355,7 @@ protected:
nscoord aAvailableBSizeForContent,
const nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker,
nscoord aMainGapSize,
nsTArray<nsIFrame*>& aPlaceholders,
mozilla::LinkedList<FlexLine>& aLines);

Просмотреть файл

@ -0,0 +1,97 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0
-->
<!--
Reference for the correctness of gaps in horizontal and vertical multi-line
flex containers.
-->
<html>
<head>
<title>Reference: Testing row and column gaps in horizontal and vertical multi-line flex containers with the space-around property and auto margins</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com">
<meta charset="utf-8">
<style>
.outerBox {
width: 200px;
height: 220px;
border: 1px solid black;
float: left;
}
.flexContainer {
display: flex;
align-content: space-around;
justify-content: space-around;
}
.rowNoWrap {
flex-flow: row nowrap;
}
.columnNoWrap {
flex-flow: column nowrap;
}
.item {
border: 1px solid blue;
background: lightblue;
width: 28px;
height: 28px;
}
.autoLBMargins {
margin-left: auto;
margin-bottom: auto;
}
.autoBMargin {
margin-bottom: auto;
}
.right20 {
margin-right: 20px;
}
.bottom40 {
margin-bottom: 40px;
}
.tb30100 {
margin-top: 30px;
margin-bottom: 100px;
}
.lr3080 {
margin-left: 30px;
margin-right: 80px;
}
.w200 {
width: 200px;
}
.h220 {
height: 220px;
}
.fleft {
float: left;
}
</style>
</head>
<body>
<div class="outerBox">
<div class="flexContainer w200 rowNoWrap tb30100">
<div class="item right20"></div>
<div class="item right20"></div>
<div class="item right20"></div>
<div class="item"></div>
</div>
<div class="flexContainer w200 rowNoWrap">
<div class="item autoLBMargins right20"></div>
<div class="item"></div>
</div>
</div>
<div class="outerBox">
<div class="flexContainer fleft h220 columnNoWrap lr3080">
<div class="item bottom40"></div>
<div class="item bottom40"></div>
<div class="item"></div>
</div>
<div class="flexContainer fleft h220 columnNoWrap">
<div class="item bottom40"></div>
<div class="item bottom40"></div>
<div class="item autoBMargin"></div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,65 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0
-->
<!--
Testcase for the correctness of gaps in horizontal and vertical multi-line
flex containers.
-->
<html>
<head>
<title>CSS Test: Testing row and column gaps in horizontal and vertical multi-line flex containers with the space-around property and auto margins</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-align/#gap-flex">
<link rel="match" href="flexbox-column-row-gap-001-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
width: 200px;
height: 220px;
border: 1px solid black;
column-gap: 10%;
row-gap: 40px;
align-content: space-around;
justify-content: space-around;
float: left;
}
.rowWrap {
flex-flow: row wrap;
}
.columnWrap {
flex-flow: column wrap;
}
.item {
border: 1px solid blue;
background: lightblue;
width: 28px;
height: 28px;
}
.autoLBMargins {
margin-left: auto;
margin-bottom: auto;
}
</style>
</head>
<body>
<div class="flexContainer rowWrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item autoLBMargins"></div>
<div class="item"></div>
</div>
<div class="flexContainer columnWrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item autoLBMargins"></div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,67 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0
-->
<!--
Testcase for the correctness of gaps in vertical writing mode
multi-line flex containers.
-->
<html>
<head>
<title>Reference: Testing row and column gaps in vertical writing mode multi-line flex containers</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
width: 220px;
height: 200px;
border: 1px solid black;
align-content: flex-start;
justify-content: flex-end;
float: left;
writing-mode: vertical-lr;
}
.rowWrap {
flex-flow: row wrap;
}
.columnWrap {
flex-flow: column wrap;
}
.item {
border: 1px solid blue;
background: lightblue;
width: 28px;
height: 28px;
}
.b20 {
margin-bottom: 20px;
}
.t20 {
margin-top: 20px;
}
.l10 {
margin-left: 10px;
}
</style>
</head>
<body>
<div class="flexContainer rowWrap">
<div class="item b20"></div>
<div class="item b20"></div>
<div class="item b20"></div>
<div class="item"></div>
<div class="item l10 b20"></div>
<div class="item l10"></div>
</div>
<div class="flexContainer columnWrap">
<div class="item"></div>
<div class="item l10"></div>
<div class="item l10"></div>
<div class="item l10"></div>
<div class="item l10"></div>
<div class="item l10 t20"></div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,62 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0
-->
<!--
Testcase for the correctness of gaps in vertical writing mode multi-line
flex containers.
-->
<html>
<head>
<title>CSS Test: Testing row and column gaps in vertical writing mode multi-line flex containers</title>
<link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-align/#gap-flex">
<link rel="match" href="flexbox-column-row-gap-002-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
width: 220px;
height: 200px;
border: 1px solid black;
column-gap: 10%;
row-gap: 10px;
align-content: flex-start;
justify-content: flex-end;
float: left;
writing-mode: vertical-lr;
}
.rowWrap {
flex-flow: row wrap;
}
.columnWrap {
flex-flow: column wrap;
}
.item {
border: 1px solid blue;
background: lightblue;
width: 28px;
height: 28px;
}
</style>
</head>
<body>
<div class="flexContainer rowWrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="flexContainer columnWrap">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>

Просмотреть файл

@ -98,6 +98,10 @@ fuzzy-if(Android,158,32) == flexbox-align-self-vert-rtl-001.xhtml flexbox-align
== flexbox-collapsed-item-horiz-002.html flexbox-collapsed-item-horiz-002-ref.html
== flexbox-collapsed-item-horiz-003.html flexbox-collapsed-item-horiz-003-ref.html
# Tests for "row gap" and "column gap"
== flexbox-column-row-gap-001.html flexbox-column-row-gap-001-ref.html
== flexbox-column-row-gap-002.html flexbox-column-row-gap-002-ref.html
# Tests for "flex-basis: content"
== flexbox-flex-basis-content-001a.html flexbox-flex-basis-content-001-ref.html
== flexbox-flex-basis-content-001b.html flexbox-flex-basis-content-001-ref.html