Backed out changeset e98d1ac584d6 (bug 1241932)

This commit is contained in:
Carsten "Tomcat" Book 2016-07-06 05:59:52 +02:00
parent d6202de12b
commit 2de695aebf
17 changed files with 200 additions and 658 deletions

View File

@ -3292,16 +3292,15 @@ Element::MozRequestPointerLock()
void void
Element::GetGridFragments(nsTArray<RefPtr<Grid>>& aResult) Element::GetGridFragments(nsTArray<RefPtr<Grid>>& aResult)
{ {
nsGridContainerFrame* frame = nsIFrame* frame = GetPrimaryFrame();
nsGridContainerFrame::GetGridFrameWithComputedInfo(GetPrimaryFrame()); if (frame && (frame->GetType() == nsGkAtoms::gridContainerFrame)) {
// If primary frame is a nsGridContainerFrame, all the next frames
// If we get a nsGridContainerFrame from the prior call, // in flow will also be nsGridContainerFrame.
// all the next-in-flow frames will also be nsGridContainerFrames. for (; frame != nullptr; frame = frame->GetNextInFlow()) {
while (frame) { aResult.AppendElement(
aResult.AppendElement( new Grid(this, static_cast<nsGridContainerFrame*>(frame))
new Grid(this, frame) );
); }
frame = static_cast<nsGridContainerFrame*>(frame->GetNextInFlow());
} }
} }

View File

@ -30,19 +30,13 @@ Grid::Grid(nsISupports* aParent,
MOZ_ASSERT(aFrame, MOZ_ASSERT(aFrame,
"Should never be instantiated with a null nsGridContainerFrame"); "Should never be instantiated with a null nsGridContainerFrame");
const ComputedGridTrackInfo* rowTrackInfo = const ComputedGridTrackInfo* rowTrackInfo = aFrame->GetComputedTemplateRows();
aFrame->GetComputedTemplateRows();
const ComputedGridLineInfo* rowLineInfo =
aFrame->GetComputedTemplateRowLines();
mRows->SetTrackInfo(rowTrackInfo); mRows->SetTrackInfo(rowTrackInfo);
mRows->SetLineInfo(rowTrackInfo, rowLineInfo); mRows->SetLineInfo(rowTrackInfo);
const ComputedGridTrackInfo* columnTrackInfo = const ComputedGridTrackInfo* colTrackInfo = aFrame->GetComputedTemplateColumns();
aFrame->GetComputedTemplateColumns(); mCols->SetTrackInfo(colTrackInfo);
const ComputedGridLineInfo* columnLineInfo = mCols->SetLineInfo(colTrackInfo);
aFrame->GetComputedTemplateColumnLines();
mCols->SetTrackInfo(columnTrackInfo);
mCols->SetLineInfo(columnTrackInfo, columnLineInfo);
} }
Grid::~Grid() Grid::~Grid()

View File

@ -60,10 +60,9 @@ GridDimension::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo)
} }
void void
GridDimension::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, GridDimension::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo)
const ComputedGridLineInfo* aLineInfo)
{ {
mLines->SetLineInfo(aTrackInfo, aLineInfo); mLines->SetLineInfo(aTrackInfo);
} }
} // namespace dom } // namespace dom

View File

@ -42,8 +42,7 @@ public:
GridTracks* Tracks() const; GridTracks* Tracks() const;
void SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo); void SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo);
void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo);
const ComputedGridLineInfo* aLineInfo);
protected: protected:
RefPtr<Grid> mParent; RefPtr<Grid> mParent;

View File

@ -63,8 +63,7 @@ GridLines::IndexedGetter(uint32_t aIndex,
} }
void void
GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo)
const ComputedGridLineInfo* aLineInfo)
{ {
mLines.Clear(); mLines.Clear();
@ -90,18 +89,12 @@ GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo,
GridLine* line = new GridLine(this); GridLine* line = new GridLine(this);
mLines.AppendElement(line); mLines.AppendElement(line);
nsTArray<nsString> lineNames;
if (aLineInfo) {
lineNames = aLineInfo->mNames.SafeElementAt(i, nsTArray<nsString>());
}
line->SetLineValues( line->SetLineValues(
nsPresContext::AppUnitsToDoubleCSSPixels(endOfLastTrack), nsPresContext::AppUnitsToDoubleCSSPixels(endOfLastTrack),
nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack - nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack -
endOfLastTrack), endOfLastTrack),
i + 1, i + 1,
lineNames nsTArray<nsString>()
); );
if (i < aTrackInfo->mEndFragmentTrack) { if (i < aTrackInfo->mEndFragmentTrack) {

View File

@ -39,8 +39,7 @@ public:
GridLine* Item(uint32_t aIndex); GridLine* Item(uint32_t aIndex);
GridLine* IndexedGetter(uint32_t aIndex, bool& aFound); GridLine* IndexedGetter(uint32_t aIndex, bool& aFound);
void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo);
const ComputedGridLineInfo* aLineInfo);
protected: protected:
RefPtr<GridDimension> mParent; RefPtr<GridDimension> mParent;

View File

@ -1,5 +1,3 @@
[chrome/test_grid_fragmentation.html]
[chrome/test_grid_lines.html]
[chrome/test_grid_object.html] [chrome/test_grid_object.html]
[chrome/test_grid_track_state.html] [chrome/test_grid_state.html]
[chrome/test_grid_tracks.html] [chrome/test_grid_repeats.html]

View File

@ -1,88 +0,0 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html><head>
<meta charset="utf-8">
<title>CSS Grid Test: Fragmentation of height:auto grid, not top-of-page</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1144096">
<link rel="help" href="https://drafts.csswg.org/css-grid/#pagination">
<link rel="match" href="grid-fragmentation-001-ref.html">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style type="text/css">
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0;
}
body { overflow:hidden; }
.columns {
position:relative;
-moz-columns: 5;
-ms-columns: 5;
-webkit-columns: 5;
columns: 5;
-moz-column-fill: auto;
-ms-column-fill: auto;
-webkit-column-fill: auto;
column-fill: auto;
border: 2px dashed;
margin-bottom: 5px;
}
.grid {
display: grid;
grid-template-columns: 30px 30px 30px;
grid-auto-rows: 50px;
grid-gap: 12px;
border:5px solid;
align-content: start;
}
span { background:lime; border:1px solid black; }
x { display:block; height:20px; }
</style>
<script>
'use strict';
SimpleTest.waitForExplicitFinish();
function runTests() {
var wrapper = document.getElementById("wrapper");
var fragments = wrapper.getGridFragments();
// test fragments of the grid
is(fragments.length, 2, "Grid is split into two fragments.");
if (fragments.length == 2) {
var grid0 = fragments[0];
var grid1 = fragments[1];
// test that both fragments have one row track and two lines
is(grid0.rows.tracks.length, 1, "Fragment 0 has one row track.");
is(grid0.rows.lines.length, 2, "Fragment 0 has two row lines.");
is(grid1.rows.tracks.length, 1, "Fragment 1 has one row track.");
is(grid1.rows.lines.length, 2, "Fragment 1 has two row lines.");
}
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<div class="columns" style="height: 100px/*fragmentainer ends in the last row*/">
<div style="padding-top:10px; background:grey">
<div id="wrapper" class="grid">
<span style="grid-row:span 2"><x></x></span>
<span style="height:60px; background:cyan"><x></x></span>
<span style="align-self:end; background:pink"><x></x></span>
<span style="grid-row:1; height:60px"><x></x></span>
</div></div></div>
</body>
</html>

View File

@ -1,117 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
body {
margin: 40px;
}
.wrapper {
display: grid;
width: 400px;
grid-gap: 10px;
grid-template-columns: 50px [first] repeat(3, [divider] 100px) [last];
grid-template-rows: [top1] repeat(1, [top2] 50px) [bot];
background-color: #f00;
}
.box {
background-color: #444;
color: #fff;
}
</style>
<script>
'use strict';
SimpleTest.waitForExplicitFinish();
function runTests() {
var wrapper = document.getElementById("wrapper");
var grid = wrapper.getGridFragments()[0];
// test property existence
isnot(typeof(grid.cols.lines), "undefined", "Grid.cols.lines property exists.");
if (typeof(grid.cols.lines) != "undefined") {
// test column line count
is(grid.cols.lines.length, 5,
"Grid.cols.lines property has length that matches grid-template-columns."
);
if (grid.cols.lines.length == 5) {
// test column line position
is(grid.cols.lines[1].start, 50, "Grid column line 2 position is as expected.");
// test column line width
is(grid.cols.lines[1].breadth, 10, "Grid column line 2 width is as expected.");
// test column line number
is(grid.cols.lines[3].number, 4, "Grid column line 4 number is as expected.");
// test column line names
is(grid.cols.lines[0].names.length, 0, "Grid column line 1 has no names.");
is(grid.cols.lines[1].names.length, 2, "Grid column line 2 has 2 names.");
isnot(grid.cols.lines[1].names.indexOf("first"), -1,
"Grid column line 2 has the name 'first'."
);
isnot(grid.cols.lines[1].names.indexOf("divider"), -1,
"Grid column line 2 has the name 'divider'."
);
is(grid.cols.lines[4].names.length, 1, "Grid column line 5 has 1 name.");
isnot(grid.cols.lines[4].names.indexOf("last"), -1,
"Grid column line 5 has the name 'last'."
);
}
}
// test property existence
isnot(typeof(grid.rows.lines), "undefined", "Grid.rows.lines property exists.");
if (typeof(grid.rows.lines) != "undefined") {
// test column line count
is(grid.rows.lines.length, 3,
"Grid.rows.lines property has length that matches grid-template-rows."
);
if (grid.rows.lines.length == 3) {
// test row line names
is(grid.rows.lines[0].names.length, 2, "Grid row line 1 has 2 names.");
isnot(grid.rows.lines[0].names.indexOf("top1"), -1,
"Grid row line 1 has the name 'top1'."
);
isnot(grid.rows.lines[0].names.indexOf("top2"), -1,
"Grid row line 1 has the name 'top2'."
);
is(grid.rows.lines[1].names.length, 1, "Grid row line 2 has 1 name.");
isnot(grid.rows.lines[1].names.indexOf("bot"), -1,
"Grid row line 2 has the name 'bot'."
);
is(grid.rows.lines[2].names.length, 0, "Grid row line 3 has no names.");
}
}
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<div id="wrapper" class="wrapper">
<div id="boxA" class="box a">A</div>
<div id="boxB" class="box b">B</div>
<div id="boxC" class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
</div>
</body>
</html>

View File

@ -29,7 +29,9 @@ SimpleTest.waitForExplicitFinish();
function runTests() { function runTests() {
var wrapper = document.getElementById("wrapper"); var wrapper = document.getElementById("wrapper");
var boxA = document.getElementById("boxA"); var boxA = document.getElementById("boxA");
var boxB = document.getElementById("boxB");
var boxC = document.getElementById("boxC");
// test function existence // test function existence
is(typeof(wrapper.getGridFragments), "function", is(typeof(wrapper.getGridFragments), "function",
"getGridFragments function exists." "getGridFragments function exists."
@ -41,12 +43,33 @@ function runTests() {
"One grid on an un-fragmented display:grid styled object." "One grid on an un-fragmented display:grid styled object."
); );
if (wrapper.getGridFragments().length == 1) { var grid = wrapper.getGridFragments()[0];
var grid = wrapper.getGridFragments()[0];
// test column and row track counts
isnot(typeof(grid.cols), "undefined", "Grid.cols property exists."); is(grid.cols.tracks.length, 4,
isnot(typeof(grid.rows), "undefined", "Grid.rows property exists."); "Grid.cols.tracks property has length that matches grid-template-columns."
} );
is(grid.rows.tracks.length, 2,
"Grid.rows.tracks property has length that matches content."
);
// test column track position
is(grid.cols.tracks[1].start, 110, "Grid column track 1 position is as expected.");
// test column track width
is(grid.cols.tracks[0].breadth, boxA.offsetWidth,
"Grid column track width (fixed size) matches item width."
);
is(grid.cols.tracks[1].breadth, boxB.offsetWidth,
"Grid column track width (flexible size) matches item width."
);
is(grid.cols.tracks[1].breadth, grid.cols.tracks[2].breadth,
"Grid column track widths with equal proportion flexible size actually are same size."
);
// test explicit / implicit tracks
is(grid.cols.tracks[0].type, "explicit", "Grid column track 0 is explicit.");
is(grid.rows.tracks[0].type, "implicit", "Grid row track 0 is implicit.");
SimpleTest.finish(); SimpleTest.finish();
} }
@ -56,8 +79,8 @@ function runTests() {
<div id="wrapper" class="wrapper"> <div id="wrapper" class="wrapper">
<div id="boxA" class="box a">A</div> <div id="boxA" class="box a">A</div>
<div class="box b">B</div> <div id="boxB" class="box b">B</div>
<div class="box c">C</div> <div id="boxC" class="box c">C</div>
<div class="box d">D</div> <div class="box d">D</div>
<div class="box e">E</div> <div class="box e">E</div>
<div class="box f">F</div> <div class="box f">F</div>

View File

@ -0,0 +1,53 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
body {
margin: 40px;
}
.wrapper {
display: grid;
width: 600px;
grid-gap: 10px;
grid-template-columns: repeat(2, 100px) repeat(auto-fill, 50px);
background-color: #f00;
}
.box {
background-color: #444;
color: #fff;
}
</style>
<script>
'use strict';
SimpleTest.waitForExplicitFinish();
function runTests() {
var wrapper = document.getElementById("wrapper");
var grid = wrapper.getGridFragments()[0];
// test state of tracks
is(grid.cols.tracks[1].state, "static", "Grid column track 1 is marked as static.");
is(grid.cols.tracks[2].state, "repeat", "Grid column track 2 is marked as repeat.");
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<div id="wrapper" class="wrapper">
<div id="boxA" class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
</div>
</body>
</html>

View File

@ -15,13 +15,6 @@ body {
grid-template-columns: 50px repeat(auto-fit, 100px); grid-template-columns: 50px repeat(auto-fit, 100px);
background-color: #f00; background-color: #f00;
} }
.wrapper2 {
display: grid;
width: 600px;
grid-gap: 0px;
grid-template-columns: repeat(2, 100px) repeat(auto-fill, 50px);
background-color: #f00;
}
.box { .box {
background-color: #444; background-color: #444;
color: #fff; color: #fff;
@ -40,20 +33,12 @@ function runTests() {
var wrapper = document.getElementById("wrapper"); var wrapper = document.getElementById("wrapper");
var grid = wrapper.getGridFragments()[0]; var grid = wrapper.getGridFragments()[0];
// test auto-fit count after removal // test count after removal
is(grid.cols.tracks.length, 2, "Grid column track array compensates for removed auto-fit columns."); is(grid.cols.tracks.length, 2, "Grid column track array compensates for removed auto-fit columns.");
var wrapper2 = document.getElementById("wrapper2"); // test state of tracks
var grid2 = wrapper2.getGridFragments()[0]; is(grid.cols.tracks[0].state, "static", "Grid column track 0 is marked as static.");
is(grid.cols.tracks[1].state, "repeat", "Grid column track 1 is marked as repeat.");
// test auto-fill count of tracks
is(grid2.cols.tracks.length, 10, "Grid column track array respects auto-fill columns.");
if (grid2.cols.tracks.length == 10) {
// test for static and repeat
is(grid2.cols.tracks[1].state, "static", "Grid column track 2 is marked as static.");
is(grid2.cols.tracks[2].state, "repeat", "Grid column track 3 is marked as repeat.");
}
SimpleTest.finish(); SimpleTest.finish();
} }
@ -65,9 +50,5 @@ function runTests() {
<div id="boxA" class="box a">A</div> <div id="boxA" class="box a">A</div>
</div> </div>
<div id="wrapper2" class="wrapper2">
<div id="boxB" class="box b">B</div>
</div>
</body> </body>
</html> </html>

View File

@ -1,85 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
body {
margin: 40px;
}
.wrapper {
display: grid;
width: 400px;
grid-gap: 10px;
grid-template-columns: 100px 1fr 1fr 100px;
background-color: #f00;
}
.box {
background-color: #444;
color: #fff;
}
</style>
<script>
'use strict';
SimpleTest.waitForExplicitFinish();
function runTests() {
var wrapper = document.getElementById("wrapper");
var grid = wrapper.getGridFragments()[0];
var boxA = document.getElementById("boxA");
var boxB = document.getElementById("boxB");
// test property existence
isnot(typeof(grid.cols.tracks), "undefined", "Grid.cols.tracks property exists.");
isnot(typeof(grid.rows.tracks), "undefined", "Grid.rows.tracks property exists.");
if ((typeof(grid.cols.tracks) != "undefined") &&
(typeof(grid.rows.tracks) != "undefined")) {
// test column and row track counts
is(grid.cols.tracks.length, 4,
"Grid.cols.tracks property has length that matches grid-template-columns."
);
is(grid.rows.tracks.length, 2,
"Grid.rows.tracks property has length that matches content."
);
if((grid.cols.tracks.length == 4) &&
(grid.rows.tracks.length == 2)) {
// test column track position
is(grid.cols.tracks[1].start, 110, "Grid column track 2 position is as expected.");
// test column track width
is(grid.cols.tracks[0].breadth, boxA.offsetWidth,
"Grid column track width (fixed size) matches item width."
);
is(grid.cols.tracks[1].breadth, boxB.offsetWidth,
"Grid column track width (flexible size) matches item width."
);
is(grid.cols.tracks[1].breadth, grid.cols.tracks[2].breadth,
"Grid column track widths with equal proportion flexible size actually are same size."
);
}
}
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<div id="wrapper" class="wrapper">
<div id="boxA" class="box a">A</div>
<div id="boxB" class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
</div>
</body>
</html>

View File

@ -322,9 +322,6 @@ FRAME_STATE_BIT(GridContainer, 20, NS_STATE_GRID_NORMAL_FLOW_CHILDREN_IN_CSS_ORD
// actually finding any pushed items when this bit is set. // actually finding any pushed items when this bit is set.
FRAME_STATE_BIT(GridContainer, 21, NS_STATE_GRID_DID_PUSH_ITEMS) FRAME_STATE_BIT(GridContainer, 21, NS_STATE_GRID_DID_PUSH_ITEMS)
// True iff computed grid values should be generated on the next reflow
FRAME_STATE_BIT(GridContainer, 22, NS_STATE_GRID_GENERATE_COMPUTED_VALUES)
// == Frame state bits that apply to SVG frames =============================== // == Frame state bits that apply to SVG frames ===============================
FRAME_STATE_GROUP(SVG, nsISVGChildFrame) FRAME_STATE_GROUP(SVG, nsISVGChildFrame)

View File

@ -1566,52 +1566,6 @@ struct nsGridContainerFrame::Tracks
return size; return size;
} }
nsTArray<nsString> GetLineNamesAtIndex(
const nsStyleGridTemplate& aGridTemplate,
const TrackSizingFunctions& aFunctions,
uint32_t aIndex)
{
nsTArray<nsString> lineNames;
bool hasRepeatAuto = aGridTemplate.HasRepeatAuto();
const nsTArray<nsTArray<nsString>>& lineNameLists(
aGridTemplate.mLineNameLists);
if (!hasRepeatAuto) {
if (aIndex < lineNameLists.Length()) {
lineNames.AppendElements(lineNameLists[aIndex]);
}
} else {
const uint32_t repeatTrackCount = aFunctions.NumRepeatTracks();
const uint32_t repeatAutoStart = aGridTemplate.mRepeatAutoIndex;
const uint32_t repeatAutoEnd = (repeatAutoStart + repeatTrackCount);
const int32_t repeatEndDelta = int32_t(repeatTrackCount - 1);
if (aIndex < repeatAutoEnd && aIndex >= repeatAutoStart) {
lineNames.AppendElements(aGridTemplate.mRepeatAutoLineNameListBefore);
} else if (aIndex <= repeatAutoEnd && aIndex > repeatAutoStart) {
lineNames.AppendElements(aGridTemplate.mRepeatAutoLineNameListAfter);
} else if (aIndex <= repeatAutoStart) {
if (aIndex < lineNameLists.Length()) {
lineNames.AppendElements(lineNameLists[aIndex]);
}
if (aIndex == repeatAutoEnd) {
uint32_t i = aIndex + 1;
if (i < lineNameLists.Length()) {
lineNames.AppendElements(lineNameLists[i]);
}
}
} else if (aIndex >= repeatAutoEnd) {
uint32_t i = aIndex - repeatEndDelta;
if (i < lineNameLists.Length()) {
lineNames.AppendElements(lineNameLists[i]);
}
}
}
return lineNames;
}
#ifdef DEBUG #ifdef DEBUG
void Dump() const void Dump() const
{ {
@ -1659,7 +1613,6 @@ struct nsGridContainerFrame::SharedGridData
nsTArray<RowData> mOriginalRowData; nsTArray<RowData> mOriginalRowData;
nsTArray<GridItemInfo> mGridItems; nsTArray<GridItemInfo> mGridItems;
nsTArray<GridItemInfo> mAbsPosItems; nsTArray<GridItemInfo> mAbsPosItems;
bool mGenerateComputedGridInfo;
/** /**
* Only set on the first-in-flow. Continuations will Initialize() their * Only set on the first-in-flow. Continuations will Initialize() their
@ -1779,11 +1732,6 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowState
} }
MOZ_ASSERT(mAbsPosItems.Length() == len + 1, "can't find GridItemInfo"); MOZ_ASSERT(mAbsPosItems.Length() == len + 1, "can't find GridItemInfo");
} }
// Copy in the computed grid info state bit
if (mSharedGridData->mGenerateComputedGridInfo) {
aGridContainerFrame->AddStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
}
} }
/** /**
@ -5631,136 +5579,85 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
aDesiredSize.SetSize(wm, desiredSize); aDesiredSize.SetSize(wm, desiredSize);
} }
if (HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES)) { // Now that we know column and row sizes and positions, set
// This state bit will never be cleared, since reflow can be called // the ComputedGridTrackInfo.
// multiple times in fragmented grids, and it's challenging to scope
// the bit to only that sequence of calls. This is relatively harmless
// since this bit is only set by accessing a ChromeOnly property, and
// therefore can't unduly slow down normal web browsing.
// Now that we know column and row sizes and positions, set // FIXME bug 1229180: Instead of doing this on every reflow, we should only
// the ComputedGridTrackInfo and related properties // set these properties if they are needed.
uint32_t colTrackCount = gridReflowState.mCols.mSizes.Length();
uint32_t colTrackCount = gridReflowState.mCols.mSizes.Length(); nsTArray<nscoord> colTrackPositions(colTrackCount);
nsTArray<nscoord> colTrackPositions(colTrackCount); nsTArray<nscoord> colTrackSizes(colTrackCount);
nsTArray<nscoord> colTrackSizes(colTrackCount); nsTArray<uint32_t> colTrackStates(colTrackCount);
nsTArray<uint32_t> colTrackStates(colTrackCount); uint32_t col = 0;
uint32_t col = 0; for (const TrackSize& sz : gridReflowState.mCols.mSizes) {
for (const TrackSize& sz : gridReflowState.mCols.mSizes) { colTrackPositions.AppendElement(sz.mPosition);
colTrackPositions.AppendElement(sz.mPosition); colTrackSizes.AppendElement(sz.mBase);
colTrackSizes.AppendElement(sz.mBase); bool isRepeat = ((col >= gridReflowState.mColFunctions.mRepeatAutoStart) &&
bool isRepeat = ((col >= gridReflowState.mColFunctions.mRepeatAutoStart) && (col < gridReflowState.mColFunctions.mRepeatAutoEnd));
(col < gridReflowState.mColFunctions.mRepeatAutoEnd)); colTrackStates.AppendElement(
colTrackStates.AppendElement(
isRepeat ?
(uint32_t)mozilla::dom::GridTrackState::Repeat :
(uint32_t)mozilla::dom::GridTrackState::Static
);
col++;
}
ComputedGridTrackInfo* colInfo = new ComputedGridTrackInfo(
gridReflowState.mColFunctions.mExplicitGridOffset,
gridReflowState.mColFunctions.NumExplicitTracks(),
0,
col,
Move(colTrackPositions),
Move(colTrackSizes),
Move(colTrackStates));
Properties().Set(GridColTrackInfo(), colInfo);
uint32_t rowTrackCount = gridReflowState.mRows.mSizes.Length();
nsTArray<nscoord> rowTrackPositions(rowTrackCount);
nsTArray<nscoord> rowTrackSizes(rowTrackCount);
nsTArray<uint32_t> rowTrackStates(rowTrackCount);
uint32_t row = 0;
for (const TrackSize& sz : gridReflowState.mRows.mSizes) {
rowTrackPositions.AppendElement(sz.mPosition);
rowTrackSizes.AppendElement(sz.mBase);
bool isRepeat = ((row >= gridReflowState.mRowFunctions.mRepeatAutoStart) &&
(row < gridReflowState.mRowFunctions.mRepeatAutoEnd));
rowTrackStates.AppendElement(
isRepeat ? isRepeat ?
(uint32_t)mozilla::dom::GridTrackState::Repeat : (uint32_t)mozilla::dom::GridTrackState::Repeat :
(uint32_t)mozilla::dom::GridTrackState::Static (uint32_t)mozilla::dom::GridTrackState::Static
); );
row++; col++;
} }
// Row info has to accomodate fragmentation of the grid, which may happen in ComputedGridTrackInfo* colInfo = new ComputedGridTrackInfo(
// later calls to Reflow. For now, presume that no more fragmentation will gridReflowState.mColFunctions.mExplicitGridOffset,
// occur. gridReflowState.mColFunctions.NumExplicitTracks(),
ComputedGridTrackInfo* rowInfo = new ComputedGridTrackInfo( 0,
gridReflowState.mRowFunctions.mExplicitGridOffset, col,
gridReflowState.mRowFunctions.NumExplicitTracks(), Move(colTrackPositions),
Move(colTrackSizes),
Move(colTrackStates));
Properties().Set(GridColTrackInfo(), colInfo);
uint32_t rowTrackCount = gridReflowState.mRows.mSizes.Length();
nsTArray<nscoord> rowTrackPositions(rowTrackCount);
nsTArray<nscoord> rowTrackSizes(rowTrackCount);
nsTArray<uint32_t> rowTrackStates(rowTrackCount);
uint32_t row = 0;
for (const TrackSize& sz : gridReflowState.mRows.mSizes) {
rowTrackPositions.AppendElement(sz.mPosition);
rowTrackSizes.AppendElement(sz.mBase);
bool isRepeat = ((row >= gridReflowState.mRowFunctions.mRepeatAutoStart) &&
(row < gridReflowState.mRowFunctions.mRepeatAutoEnd));
rowTrackStates.AppendElement(
isRepeat ?
(uint32_t)mozilla::dom::GridTrackState::Repeat :
(uint32_t)mozilla::dom::GridTrackState::Static
);
row++;
}
// Row info has to accomodate fragmentation of the grid, which may happen in
// later calls to Reflow. For now, presume that no more fragmentation will
// occur.
ComputedGridTrackInfo* rowInfo = new ComputedGridTrackInfo(
gridReflowState.mRowFunctions.mExplicitGridOffset,
gridReflowState.mRowFunctions.NumExplicitTracks(),
gridReflowState.mStartRow,
row,
Move(rowTrackPositions),
Move(rowTrackSizes),
Move(rowTrackStates));
Properties().Set(GridRowTrackInfo(), rowInfo);
if (prevInFlow) {
// This frame is fragmenting rows from a previous frame, so patch up
// the prior GridRowTrackInfo with a new end row.
ComputedGridTrackInfo* priorRowInfo =
prevInFlow->Properties().Get(GridRowTrackInfo());
ComputedGridTrackInfo* revisedPriorRowInfo = new ComputedGridTrackInfo(
priorRowInfo->mNumLeadingImplicitTracks,
priorRowInfo->mNumExplicitTracks,
priorRowInfo->mStartFragmentTrack,
gridReflowState.mStartRow, gridReflowState.mStartRow,
row, Move(priorRowInfo->mPositions),
Move(rowTrackPositions), Move(priorRowInfo->mSizes),
Move(rowTrackSizes), Move(priorRowInfo->mStates));
Move(rowTrackStates)); prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo);
Properties().Set(GridRowTrackInfo(), rowInfo);
if (prevInFlow) {
// This frame is fragmenting rows from a previous frame, so patch up
// the prior GridRowTrackInfo with a new end row.
// FIXME: This can be streamlined and/or removed when bug 1151204 lands.
ComputedGridTrackInfo* priorRowInfo =
prevInFlow->Properties().Get(GridRowTrackInfo());
// Adjust track positions based on the first track in this fragment.
MOZ_ASSERT(priorRowInfo->mPositions.Length() >
priorRowInfo->mStartFragmentTrack);
nscoord delta =
priorRowInfo->mPositions[priorRowInfo->mStartFragmentTrack];
for (nscoord& pos : priorRowInfo->mPositions) {
pos -= delta;
}
ComputedGridTrackInfo* revisedPriorRowInfo = new ComputedGridTrackInfo(
priorRowInfo->mNumLeadingImplicitTracks,
priorRowInfo->mNumExplicitTracks,
priorRowInfo->mStartFragmentTrack,
gridReflowState.mStartRow,
Move(priorRowInfo->mPositions),
Move(priorRowInfo->mSizes),
Move(priorRowInfo->mStates));
prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo);
}
// Generate the line info properties. We need to provide the number of
// repeat tracks produced in the reflow.
// Generate column lines first.
uint32_t capacity = gridReflowState.mColFunctions.NumRepeatTracks() +
gridReflowState.mCols.mSizes.Length();
nsTArray<nsTArray<nsString>> columnLineNames(capacity);
for (col = 0; col <= gridReflowState.mCols.mSizes.Length(); col++) {
columnLineNames.AppendElement(
gridReflowState.mCols.GetLineNamesAtIndex(
gridReflowState.mGridStyle->mGridTemplateColumns,
gridReflowState.mColFunctions,
col));
}
ComputedGridLineInfo* columnLineInfo = new ComputedGridLineInfo(
Move(columnLineNames));
Properties().Set(GridColumnLineInfo(), columnLineInfo);
// Generate row lines next.
capacity = gridReflowState.mRowFunctions.NumRepeatTracks() +
gridReflowState.mRows.mSizes.Length();
nsTArray<nsTArray<nsString>> rowLineNames(capacity);
for (row = 0; row <= gridReflowState.mRows.mSizes.Length(); row++) {
rowLineNames.AppendElement(
gridReflowState.mRows.GetLineNamesAtIndex(
gridReflowState.mGridStyle->mGridTemplateRows,
gridReflowState.mRowFunctions,
row));
}
ComputedGridLineInfo* rowLineInfo = new ComputedGridLineInfo(
Move(rowLineNames));
Properties().Set(GridRowLineInfo(), rowLineInfo);
} }
if (!prevInFlow) { if (!prevInFlow) {
@ -5799,9 +5696,6 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
sharedGridData->mGridItems.SwapElements(gridReflowState.mGridItems); sharedGridData->mGridItems.SwapElements(gridReflowState.mGridItems);
sharedGridData->mAbsPosItems.Clear(); sharedGridData->mAbsPosItems.Clear();
sharedGridData->mAbsPosItems.SwapElements(gridReflowState.mAbsPosItems); sharedGridData->mAbsPosItems.SwapElements(gridReflowState.mAbsPosItems);
sharedGridData->mGenerateComputedGridInfo =
HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
} else if (sharedGridData && !GetNextInFlow()) { } else if (sharedGridData && !GetNextInFlow()) {
Properties().Delete(SharedGridData::Prop()); Properties().Delete(SharedGridData::Prop());
} }
@ -6097,57 +5991,3 @@ nsGridContainerFrame::TrackSize::Dump() const
} }
#endif // DEBUG #endif // DEBUG
nsGridContainerFrame*
nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame)
{
// Prepare a lambda function that we may need to call multiple times.
auto GetGridContainerFrame = [](nsIFrame *aFrame) {
// Return the aFrame's content insertion frame, iff it is
// a grid container.
nsGridContainerFrame* gridFrame = nullptr;
if (aFrame) {
nsIFrame* contentFrame = aFrame->GetContentInsertionFrame();
if (contentFrame &&
(contentFrame->GetType() == nsGkAtoms::gridContainerFrame)) {
gridFrame = static_cast<nsGridContainerFrame*>(contentFrame);
}
}
return gridFrame;
};
nsGridContainerFrame* gridFrame = GetGridContainerFrame(aFrame);
if (gridFrame) {
// if any of our properties are missing, generate them
bool reflowNeeded = (!gridFrame->Properties().Has(GridColTrackInfo()) ||
!gridFrame->Properties().Has(GridRowTrackInfo()) ||
!gridFrame->Properties().Has(GridColumnLineInfo()) ||
!gridFrame->Properties().Has(GridRowLineInfo()));
if (reflowNeeded) {
// Trigger a reflow that generates additional grid property data.
nsIPresShell* shell = gridFrame->PresContext()->PresShell();
gridFrame->AddStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
shell->FrameNeedsReflow(gridFrame,
nsIPresShell::eResize,
NS_FRAME_IS_DIRTY);
shell->FlushPendingNotifications(Flush_Layout);
// Since the reflow may have side effects, get the grid frame again.
gridFrame = GetGridContainerFrame(aFrame);
// Assert the grid properties are present
MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridColTrackInfo()));
MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridRowTrackInfo()));
MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridColumnLineInfo()));
MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridRowLineInfo()));
}
}
return gridFrame;
}

View File

@ -51,14 +51,6 @@ struct ComputedGridTrackInfo
nsTArray<nscoord> mSizes; nsTArray<nscoord> mSizes;
nsTArray<uint32_t> mStates; nsTArray<uint32_t> mStates;
}; };
struct ComputedGridLineInfo
{
ComputedGridLineInfo(nsTArray<nsTArray<nsString>>&& aNames)
: mNames(aNames)
{}
nsTArray<nsTArray<nsString>> mNames;
};
} // namespace mozilla } // namespace mozilla
class nsGridContainerFrame final : public nsContainerFrame class nsGridContainerFrame final : public nsContainerFrame
@ -68,7 +60,6 @@ public:
NS_DECL_QUERYFRAME_TARGET(nsGridContainerFrame) NS_DECL_QUERYFRAME_TARGET(nsGridContainerFrame)
NS_DECL_QUERYFRAME NS_DECL_QUERYFRAME
typedef mozilla::ComputedGridTrackInfo ComputedGridTrackInfo; typedef mozilla::ComputedGridTrackInfo ComputedGridTrackInfo;
typedef mozilla::ComputedGridLineInfo ComputedGridLineInfo;
// nsIFrame overrides // nsIFrame overrides
void Reflow(nsPresContext* aPresContext, void Reflow(nsPresContext* aPresContext,
@ -114,50 +105,18 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemContainingBlockRect, nsRect) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemContainingBlockRect, nsRect)
/**
* These properties are created by a call to
* nsGridContainerFrame::GetGridFrameWithComputedInfo, typically from
* Element::GetGridFragments.
*/
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateColumns() const ComputedGridTrackInfo* GetComputedTemplateColumns()
{ {
const ComputedGridTrackInfo* info = Properties().Get(GridColTrackInfo()); return Properties().Get(GridColTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
} }
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateRows() const ComputedGridTrackInfo* GetComputedTemplateRows()
{ {
const ComputedGridTrackInfo* info = Properties().Get(GridRowTrackInfo()); return Properties().Get(GridRowTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
} }
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateColumnLines()
{
const ComputedGridLineInfo* info = Properties().Get(GridColumnLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateRowLines()
{
const ComputedGridLineInfo* info = Properties().Get(GridRowLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
/**
* Return a containing grid frame, and ensure it has computed grid info
* @return nullptr if aFrame has no grid container, or frame was destroyed
* @note this might destroy layout/style data since it may flush layout
*/
static nsGridContainerFrame* GetGridFrameWithComputedInfo(nsIFrame* aFrame);
struct TrackSize; struct TrackSize;
struct GridItemInfo; struct GridItemInfo;
struct GridReflowState; struct GridReflowState;

View File

@ -2732,15 +2732,14 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetGridTemplateColumns() nsComputedDOMStyle::DoGetGridTemplateColumns()
{ {
const ComputedGridTrackInfo* info = nullptr; const ComputedGridTrackInfo* info = nullptr;
if (mInnerFrame) {
nsGridContainerFrame* gridFrame = nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame();
nsGridContainerFrame::GetGridFrameWithComputedInfo( if (gridContainerCandidate &&
mContent->GetPrimaryFrame()); gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) {
info = static_cast<nsGridContainerFrame*>(gridContainerCandidate)->
if (gridFrame) { GetComputedTemplateColumns();
info = gridFrame->GetComputedTemplateColumns(); }
} }
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, info); return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, info);
} }
@ -2748,15 +2747,14 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetGridTemplateRows() nsComputedDOMStyle::DoGetGridTemplateRows()
{ {
const ComputedGridTrackInfo* info = nullptr; const ComputedGridTrackInfo* info = nullptr;
if (mInnerFrame) {
nsGridContainerFrame* gridFrame = nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame();
nsGridContainerFrame::GetGridFrameWithComputedInfo( if (gridContainerCandidate &&
mContent->GetPrimaryFrame()); gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) {
info = static_cast<nsGridContainerFrame*>(gridContainerCandidate)->
if (gridFrame) { GetComputedTemplateRows();
info = gridFrame->GetComputedTemplateRows(); }
} }
return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, info); return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, info);
} }