Commit 69243d0f authored by rego@igalia.com's avatar rego@igalia.com

[CSS Grid Layout] Fix issues adding new items to grid

First if the grid auto flow property is different to none, the grid is
marked as dirty when a new child is added. Because of if it contains
auto-placed items, they might need to be re-positioned.

Then if the new item has definite positions and auto flow is none, the
grid will grow as required and place the new item without being marked
as dirty.

The test was not working properly, as it was adding the PASS messages
as auto-placed grid items which was marking the grid as dirty and force
a re-calculation of the position.

Moving the results of the test to a different div make the test fails
without this patch. Test expectation was updated accordingly.

BUG=248151
TEST=fast/css-grid-layout/grid-item-addition-auto-placement-update.html

Review URL: https://codereview.chromium.org/198703004

git-svn-id: svn://svn.chromium.org/blink/trunk@169784 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 1a0a1c26
This test checks that the tracks' auto positions are recomputed after adding a grid item.
XXXXX XXXXX XXXXX
XXXXX XXXXX XXXXX
XXXXX XXXXX XXXXX
XXXXX XXXXX XXXXX
PASS
PASS
PASS
PASS
PASS
XXXXX XXXXX XXXXX
PASS
PASS
PASS
PASS
PASS
XXXXX XXXXX XXXXX
PASS
PASS
PASS
PASS
PASS
XXXXX XXXXX XXXXX
PASS
PASS
PASS
......
......@@ -21,30 +21,31 @@ function testAddition(gridElementID, position, autoFlowElementID, size)
var autoFlowElement = document.getElementById(autoFlowElementID);
autoFlowElement.setAttribute("data-expected-width", size.width);
autoFlowElement.setAttribute("data-expected-height", size.height);
checkLayout("#" + autoFlowElementID);
checkLayout("#" + autoFlowElementID, document.getElementById("test-output"));
}
function testAdditions()
{
checkLayout("#autoFlowColumnElement");
var testOutput = document.getElementById("test-output");
checkLayout("#autoFlowColumnElement", testOutput);
testAddition("gridAutoFlowColumn", { 'row': '1', 'column': '1' }, "autoFlowColumnElement", { 'width': '50', 'height': '100' });
testAddition("gridAutoFlowColumn", { 'row': '1', 'column': '2' }, "autoFlowColumnElement", { 'width': '50', 'height': '100' });
testAddition("gridAutoFlowColumn", { 'row': '2', 'column': '2' }, "autoFlowColumnElement", { 'width': '50', 'height': '100' });
testAddition("gridAutoFlowColumn", { 'row': '2', 'column': '1' }, "autoFlowColumnElement", { 'width': '170', 'height': '50' });
checkLayout("#autoFlowRowElement");
checkLayout("#autoFlowRowElement", testOutput);
testAddition("gridAutoFlowRow", { 'row': '1', 'column': '1' }, "autoFlowRowElement", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowRow", { 'row': '2', 'column': '1' }, "autoFlowRowElement", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowRow", { 'row': '2', 'column': '2' }, "autoFlowRowElement", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowRow", { 'row': '1', 'column': '2' }, "autoFlowRowElement", { 'width': '50', 'height': '30' });
checkLayout("#gridAutoFlowColumnWithAuto");
checkLayout("#gridAutoFlowColumnWithAuto", testOutput);
testAddition("gridAutoFlowColumnWithAuto", { 'row': 'auto', 'column': '1' }, "autoFlowColumnElementWithAuto", { 'width': '50', 'height': '100' });
testAddition("gridAutoFlowColumnWithAuto", { 'row': '1', 'column': '1' }, "autoFlowColumnElementWithAuto", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowColumnWithAuto", { 'row': 'auto', 'column': '2' }, "autoFlowColumnElementWithAuto", { 'width': '100', 'height': '100' });
testAddition("gridAutoFlowColumnWithAuto", { 'row': '2', 'column': '2' }, "autoFlowColumnElementWithAuto", { 'width': '170', 'height': '50' });
checkLayout("#gridAutoFlowRowWithAuto");
checkLayout("#gridAutoFlowRowWithAuto", testOutput);
testAddition("gridAutoFlowRowWithAuto", { 'row': '1', 'column': 'auto' }, "autoFlowRowElementWithAuto", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowRowWithAuto", { 'row': 'auto', 'column': '1' }, "autoFlowRowElementWithAuto", { 'width': '100', 'height': '50' });
testAddition("gridAutoFlowRowWithAuto", { 'row': '1', 'column': '2' }, "autoFlowRowElementWithAuto", { 'width': '50', 'height': '100' });
......@@ -80,5 +81,7 @@ window.addEventListener("load", testAdditions, false);
</div>
</div>
<div id="test-output"></div>
</body>
</html>
......@@ -191,19 +191,27 @@ void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
return;
}
if (style()->gridAutoFlow() != AutoFlowNone) {
// The grid needs to be recomputed as it might contain auto-placed items that will change their position.
dirtyGrid();
return;
}
RenderBox* newChildBox = toRenderBox(newChild);
OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, ForRows);
OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox, ForColumns);
if (!rowPositions || !columnPositions) {
// The new child requires the auto-placement algorithm to run so we need to recompute the grid fully.
dirtyGrid();
return;
} else {
if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCount() <= columnPositions->finalPositionIndex) {
// FIXME: We could just insert the new child provided we had a primitive to arbitrarily grow the grid.
dirtyGrid();
} else {
insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
}
// Ensure that the grid is big enough to contain new grid item.
if (gridRowCount() <= rowPositions->finalPositionIndex)
growGrid(ForRows, rowPositions->finalPositionIndex);
if (gridColumnCount() <= columnPositions->finalPositionIndex)
growGrid(ForColumns, columnPositions->finalPositionIndex);
insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
}
}
......@@ -708,16 +716,18 @@ bool RenderGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
}
#endif
void RenderGrid::growGrid(GridTrackSizingDirection direction)
void RenderGrid::growGrid(GridTrackSizingDirection direction, size_t maximumPositionIndex)
{
if (direction == ForColumns) {
const size_t oldColumnSize = m_grid[0].size();
ASSERT(maximumPositionIndex >= m_grid[0].size());
for (size_t row = 0; row < m_grid.size(); ++row)
m_grid[row].grow(oldColumnSize + 1);
m_grid[row].grow(maximumPositionIndex + 1);
} else {
ASSERT(maximumPositionIndex >= m_grid.size());
const size_t oldRowSize = m_grid.size();
m_grid.grow(oldRowSize + 1);
m_grid[oldRowSize].grow(m_grid[0].size());
m_grid.grow(maximumPositionIndex + 1);
for (size_t row = oldRowSize; row < m_grid.size(); ++row)
m_grid[row].grow(m_grid[0].size());
}
}
......@@ -823,7 +833,7 @@ void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au
continue;
}
growGrid(autoPlacementMinorAxisDirection());
growGrid(autoPlacementMinorAxisDirection(), autoPlacementMinorAxisDirection() == ForColumns ? m_grid[0].size() : m_grid.size());
OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea();
ASSERT(emptyGridArea);
insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
......@@ -862,7 +872,7 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem)
// We didn't find an empty grid area so we need to create an extra major axis line and insert our gridItem in it.
const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex;
const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size();
growGrid(autoPlacementMajorAxisDirection());
growGrid(autoPlacementMajorAxisDirection(), autoPlacementMajorAxisDirection() == ForColumns ? m_grid[0].size() : m_grid.size());
insertItemIntoGrid(gridItem, rowIndex, columnIndex);
}
......
......@@ -80,7 +80,7 @@ private:
LayoutUnit computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection, const Length&) const;
void resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
void growGrid(GridTrackSizingDirection);
void growGrid(GridTrackSizingDirection, size_t maximumPosition);
void insertItemIntoGrid(RenderBox*, size_t rowTrack, size_t columnTrack);
void insertItemIntoGrid(RenderBox*, const GridCoordinate&);
void placeItemsOnGrid();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment