Commit 6fa74132 authored by sergio@webkit.org's avatar sergio@webkit.org

[CSS Grid Layout] Handle 'span' positions during layout

https://bugs.webkit.org/show_bug.cgi?id=119756

Reviewed by Andreas Kling.

From Blink r149133 by <jchaffraix@chromium.org>

Source/WebCore:

Properly handle the 'span' keyword during layout. We only had
parsing support so far but with this change we are able to
recognize these positions and act accordingly.

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::resolveGridPositionsFromStyle):
(WebCore::RenderGrid::resolveGridPositionAgainstOppositePosition):
* rendering/RenderGrid.h:
* rendering/style/GridPosition.h:
(WebCore::GridPosition::shouldBeResolvedAgainstOppositePosition):

LayoutTests:

Added some new test cases to verify that we properly resolve
'span' positions.

* fast/css-grid-layout/grid-item-negative-position-resolution-expected.txt:
* fast/css-grid-layout/grid-item-negative-position-resolution.html:
* fast/css-grid-layout/grid-item-spanning-resolution-expected.txt:
* fast/css-grid-layout/grid-item-spanning-resolution.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154753 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 422085a8
2013-08-28 Sergio Villar Senin <svillar@igalia.com>
[CSS Grid Layout] Handle 'span' positions during layout
https://bugs.webkit.org/show_bug.cgi?id=119756
Reviewed by Andreas Kling.
From Blink r149133 by <jchaffraix@chromium.org>
Added some new test cases to verify that we properly resolve
'span' positions.
* fast/css-grid-layout/grid-item-negative-position-resolution-expected.txt:
* fast/css-grid-layout/grid-item-negative-position-resolution.html:
* fast/css-grid-layout/grid-item-spanning-resolution-expected.txt:
* fast/css-grid-layout/grid-item-spanning-resolution.html:
2013-08-28 Ádám Kallai <kadam@inf.u-szeged.hu>
[Qt] Delete unnecessary empty directories.
......@@ -27,6 +27,26 @@ if (window.testRunner)
-webkit-grid-row: -1 / auto;
}
.endSpanGrowGridInColumnDirection {
-webkit-grid-column: -2 / span 3;
-webkit-grid-row: 1;
}
.endSpanGrowGridInRowDirection {
-webkit-grid-column: 1;
-webkit-grid-row: -2 / span 3;
}
.negativeEndPositionStartSpanInColumnDirection {
-webkit-grid-column: span / -1;
-webkit-grid-row: 1;
}
.negativeEndPositionStartSpanInRowDirection {
-webkit-grid-column: 1;
-webkit-grid-row: span 5 / -1;
}
.negativeEndPositionStartNegativeInColumnDirection {
-webkit-grid-column: -3 / -1;
-webkit-grid-row: 1;
......@@ -54,6 +74,30 @@ if (window.testRunner)
</div>
</div>
<div style="position: relative">
<div class="grid" data-expected-width="550" data-expected-height="150">
<div class="sizedToGridArea endSpanGrowGridInColumnDirection" data-offset-x="50" data-offset-y="0" data-expected-width="500" data-expected-height="50"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" data-expected-width="150" data-expected-height="550">
<div class="sizedToGridArea endSpanGrowGridInRowDirection" data-offset-x="0" data-offset-y="50" data-expected-width="50" data-expected-height="500"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" data-expected-width="150" data-expected-height="150">
<div class="sizedToGridArea negativeEndPositionStartSpanInColumnDirection" data-offset-x="50" data-offset-y="0" data-expected-width="100" data-expected-height="50"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" data-expected-width="150" data-expected-height="150">
<div class="sizedToGridArea negativeEndPositionStartSpanInRowDirection" data-offset-x="0" data-offset-y="0" data-expected-width="50" data-expected-height="150"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" data-expected-width="150" data-expected-height="150">
<div class="sizedToGridArea negativeEndPositionStartNegativeInColumnDirection" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="50"></div>
......
......@@ -12,3 +12,8 @@ PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
......@@ -49,6 +49,31 @@ if (window.testRunner)
-webkit-grid-column: 3 / 4;
-webkit-grid-row: 3 / 4;
}
.firstRowSpanning3SecondColumn {
-webkit-grid-column: 2;
-webkit-grid-row: 1 / span 3;
}
.thirdRowSecondColumnSpanning2 {
-webkit-grid-column: 2 / span 2;
-webkit-grid-row: 3;
}
.spanning3Row5SecondColumn {
-webkit-grid-column: 2;
-webkit-grid-row: span 3 / 5;
}
.thirdRowSpanning2Column3 {
-webkit-grid-column: span 2 / 3;
-webkit-grid-row: 3;
}
.underflowSpanning {
-webkit-grid-column: span 3 / 3;
-webkit-grid-row: span 8 / 4;
}
</style>
<script src="../../resources/check-layout.js"></script>
<body onload="checkLayout('.grid');">
......@@ -126,5 +151,33 @@ if (window.testRunner)
<div class="sizedToGridArea secondRowSecondColumnNoSpan" data-offset-x="50" data-offset-y="25" data-expected-width="50" data-expected-height="25"></div>
<div class="sizedToGridArea thirdRowThirdColumnNoSpan" data-offset-x="100" data-offset-y="50" data-expected-width="50" data-expected-height="25"></div>
</div>
<div style="position: relative">
<div class="grid" id="bigGrid" data-expected-width="200" data-expected-height="100">
<div class="sizedToGridArea firstRowSpanning3SecondColumn" data-offset-x="50" data-offset-y="0" data-expected-width="50" data-expected-height="75"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" id="bigGrid" data-expected-width="200" data-expected-height="100">
<div class="sizedToGridArea thirdRowSecondColumnSpanning2" data-offset-x="50" data-offset-y="50" data-expected-width="100" data-expected-height="25"></div>
</div>
<div style="position: relative">
<div class="grid" id="bigGrid" data-expected-width="200" data-expected-height="100">
<div class="sizedToGridArea spanning3Row5SecondColumn" data-offset-x="50" data-offset-y="25" data-expected-width="50" data-expected-height="75"></div>
</div>
</div>
<div style="position: relative">
<div class="grid" id="bigGrid" data-expected-width="200" data-expected-height="100">
<div class="sizedToGridArea thirdRowSpanning2Column3" data-offset-x="0" data-offset-y="50" data-expected-width="100" data-expected-height="25"></div>
</div>
<div style="position: relative">
<div class="grid" id="bigGrid" data-expected-width="200" data-expected-height="100">
<div class="sizedToGridArea underflowSpanning" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="75"></div>
</div>
</body>
</html>
2013-08-28 Sergio Villar Senin <svillar@igalia.com>
[CSS Grid Layout] Handle 'span' positions during layout
https://bugs.webkit.org/show_bug.cgi?id=119756
Reviewed by Andreas Kling.
From Blink r149133 by <jchaffraix@chromium.org>
Properly handle the 'span' keyword during layout. We only had
parsing support so far but with this change we are able to
recognize these positions and act accordingly.
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::resolveGridPositionsFromStyle):
(WebCore::RenderGrid::resolveGridPositionAgainstOppositePosition):
* rendering/RenderGrid.h:
* rendering/style/GridPosition.h:
(WebCore::GridPosition::shouldBeResolvedAgainstOppositePosition):
2013-08-28 Antti Koivisto <antti@apple.com>
Factor descendant iterator assertions into a class.
......@@ -720,6 +720,9 @@ PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveGridPositionsFromStyle(const
const GridPosition& finalPosition = (direction == ForColumns) ? gridItem->style()->gridItemColumnEnd() : gridItem->style()->gridItemRowEnd();
const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
// We should NEVER see both spans as they should have been handled during style resolve.
ASSERT(!initialPosition.isSpan() || !finalPosition.isSpan());
if (initialPosition.isAuto() && finalPosition.isAuto()) {
if (style()->gridAutoFlow() == AutoFlowNone)
return adoptPtr(new GridSpan(0, 0));
......@@ -728,16 +731,16 @@ PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveGridPositionsFromStyle(const
return nullptr;
}
if (initialPosition.isAuto()) {
// Infer the position from the final position ('auto / 1' case).
if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
// Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
const size_t finalResolvedPosition = resolveGridPositionFromStyle(finalPosition, finalPositionSide);
return adoptPtr(new GridSpan(finalResolvedPosition, finalResolvedPosition));
return resolveGridPositionAgainstOppositePosition(finalResolvedPosition, initialPosition, initialPositionSide);
}
if (finalPosition.isAuto()) {
// Infer our position from the initial position ('1 / auto' case).
if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
// Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
const size_t initialResolvedPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
return adoptPtr(new GridSpan(initialResolvedPosition, initialResolvedPosition));
return resolveGridPositionAgainstOppositePosition(initialResolvedPosition, finalPosition, finalPositionSide);
}
size_t resolvedInitialPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
......@@ -790,6 +793,25 @@ size_t RenderGrid::resolveGridPositionFromStyle(const GridPosition& position, Gr
return 0;
}
PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
{
if (position.isAuto())
return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
ASSERT(position.isSpan());
ASSERT(position.spanPosition() > 0);
// 'span 1' is contained inside a single grid track regardless of the direction.
// That's why the CSS span value is one more than the offset we apply.
size_t positionOffset = position.spanPosition() - 1;
if (side == ColumnStartSide || side == RowStartSide) {
size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePosition - positionOffset);
return GridSpan::create(initialResolvedPosition, resolvedOppositePosition);
}
return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition + positionOffset);
}
LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, TrackSizingDirection direction, const Vector<GridTrack>& tracks) const
{
const GridCoordinate& coordinate = cachedGridCoordinate(child);
......
......@@ -59,6 +59,11 @@ private:
LayoutUnit computePreferredTrackWidth(const Length&, size_t) const;
struct GridSpan {
static PassOwnPtr<GridSpan> create(size_t initialPosition, size_t finalPosition)
{
return adoptPtr(new GridSpan(initialPosition, finalPosition));
}
GridSpan(size_t initialPosition, size_t finalPosition)
: initialPositionIndex(initialPosition)
, finalPositionIndex(finalPosition)
......@@ -130,6 +135,7 @@ private:
GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, TrackSizingDirection, size_t) const;
PassOwnPtr<GridSpan> resolveGridPositionsFromStyle(const RenderBox*, TrackSizingDirection) const;
size_t resolveGridPositionFromStyle(const GridPosition&, GridPositionSide) const;
PassOwnPtr<GridSpan> resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, GridPositionSide) const;
LayoutUnit gridAreaBreadthForChild(const RenderBox* child, TrackSizingDirection, const Vector<GridTrack>&) const;
......
......@@ -86,6 +86,10 @@ public:
return m_type == other.m_type && m_integerPosition == other.m_integerPosition;
}
bool shouldBeResolvedAgainstOppositePosition() const
{
return isAuto() || isSpan();
}
private:
GridPositionType m_type;
int m_integerPosition;
......
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