Changeset 155181 in webkit


Ignore:
Timestamp:
Sep 6, 2013 1:04:33 AM (11 years ago)
Author:
svillar@igalia.com
Message:

[CSS Grid Layout] Resolve named grid lines
https://bugs.webkit.org/show_bug.cgi?id=119632

Reviewed by Andreas Kling.

From Blink r152659, r153794 by <jchaffraix@chromium.org>

Source/WebCore:

Test: fast/css-grid-layout/grid-item-named-grid-line-resolution.html

This change adds the code which translates from a raw named grid
line (stored in RenderStyle) to its actual grid position. This
even includes named grid resolution for grid lines with the 'span'
keyword.

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::explicitGridSizeForSide):
(WebCore::adjustGridPositionForRowEndColumnEndSide):
(WebCore::adjustGridPositionForSide):
(WebCore::RenderGrid::resolveNamedGridLinePositionFromStyle):
(WebCore::RenderGrid::resolveGridPositionFromStyle):
(WebCore::RenderGrid::resolveGridPositionAgainstOppositePosition):
(WebCore::RenderGrid::resolveNamedGridLinePositionAgainstOppositePosition):
(WebCore::RenderGrid::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition):
(WebCore::RenderGrid::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):

  • rendering/RenderGrid.h:

LayoutTests:

Added a new test to check named grid lines resolution. This also
provides some more new test cases with named grid lines and
negative positions.

  • fast/css-grid-layout/grid-item-named-grid-line-resolution-expected.txt: Added.
  • fast/css-grid-layout/grid-item-named-grid-line-resolution.html: Added.
  • fast/css-grid-layout/grid-item-negative-position-resolution-expected.txt:
  • fast/css-grid-layout/grid-item-negative-position-resolution.html:
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r155179 r155181  
     12013-09-06  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [CSS Grid Layout] Resolve named grid lines
     4        https://bugs.webkit.org/show_bug.cgi?id=119632
     5
     6        Reviewed by Andreas Kling.
     7
     8        From Blink r152659, r153794 by <jchaffraix@chromium.org>
     9
     10        Added a new test to check named grid lines resolution. This also
     11        provides some more new test cases with named grid lines and
     12        negative positions.
     13
     14        * fast/css-grid-layout/grid-item-named-grid-line-resolution-expected.txt: Added.
     15        * fast/css-grid-layout/grid-item-named-grid-line-resolution.html: Added.
     16        * fast/css-grid-layout/grid-item-negative-position-resolution-expected.txt:
     17        * fast/css-grid-layout/grid-item-negative-position-resolution.html:
     18
    1192013-09-06  Dirk Schulze  <krit@webkit.org>
    220
  • trunk/LayoutTests/fast/css-grid-layout/grid-item-negative-position-resolution-expected.txt

    r154753 r155181  
    99PASS
    1010PASS
     11PASS
     12PASS
     13PASS
     14PASS
     15PASS
     16PASS
     17PASS
     18PASS
  • trunk/LayoutTests/fast/css-grid-layout/grid-item-negative-position-resolution.html

    r154753 r155181  
    88<style>
    99.grid {
    10     -webkit-grid-definition-columns: 50px 100px;
    11     -webkit-grid-definition-rows: 50px 100px;
     10    -webkit-grid-definition-columns: 'first' 50px 'middle' 100px 'last';
     11    -webkit-grid-definition-rows: 'first' 50px 'middle' 100px 'last';
    1212    /* To detect how much we extend the grid. */
    1313    -webkit-grid-auto-columns: 200px;
     
    2828}
    2929
     30.lastNamedGridLineStartPositionGrowGridInRowDirection {
     31    -webkit-grid-column: 1;
     32    -webkit-grid-row: -1 / auto;
     33}
     34
     35.lastNamedGridLineStartPositionGrowGridInColumnDirection {
     36    -webkit-grid-column: "last" / auto;
     37    -webkit-grid-row: 1;
     38}
     39
     40.negativeStartPositionGrowGridInRowDirection {
     41    -webkit-grid-column: 1;
     42    -webkit-grid-row: "last" / auto;
     43}
     44
    3045.endSpanGrowGridInColumnDirection {
    3146    -webkit-grid-column: -2 / span 3;
     
    3853}
    3954
     55.namedEndSpanGrowGridInColumnDirection {
     56    -webkit-grid-column: -1 "middle" / span 3;
     57    -webkit-grid-row: 1;
     58}
     59
     60.namedEndSpanGrowGridInRowDirection {
     61    -webkit-grid-column: 1;
     62    -webkit-grid-row: 2 "middle" / span 3;
     63}
     64
    4065.negativeEndPositionStartSpanInColumnDirection {
    4166    -webkit-grid-column: span / -1;
     
    4873}
    4974
     75.negativeNamedGridLineEndPositionStartSpanInColumnDirection {
     76    -webkit-grid-column: span / "last";
     77    -webkit-grid-row: 1;
     78}
     79
     80.negativeNamedGridLineEndPositionStartSpanInRowDirection {
     81    -webkit-grid-column: 1;
     82    -webkit-grid-row: span 5 / "last";
     83}
     84
    5085.negativeEndPositionStartNegativeInColumnDirection {
    5186    -webkit-grid-column: -3 / -1;
     
    5691    -webkit-grid-column: -5 / -2;
    5792    -webkit-grid-row: 1;
     93}
     94
     95.namedGridLineEndPositionStartNegativeInColumnDirection {
     96    -webkit-grid-column: -3 / 10 "last";
     97    -webkit-grid-row: 1;
     98}
     99
     100.namedGridLineEndPositionStartNegativeInRowDirection {
     101    grid-column: -5 / -2 "middle";
     102    grid-row: 1;
    58103}
    59104</style>
     
    71116<div style="position: relative">
    72117<div class="grid" data-expected-width="150" data-expected-height="350">
     118    <div class="sizedToGridArea lastNamedGridLineStartPositionGrowGridInRowDirection" data-offset-x="0" data-offset-y="150" data-expected-width="50" data-expected-height="200"></div>
     119</div>
     120</div>
     121
     122<div style="position: relative">
     123<div class="grid" data-expected-width="350" data-expected-height="150">
     124    <div class="sizedToGridArea lastNamedGridLineStartPositionGrowGridInColumnDirection" data-offset-x="150" data-offset-y="0" data-expected-width="200" data-expected-height="50"></div>
     125</div>
     126</div>
     127
     128<div style="position: relative">
     129<div class="grid" data-expected-width="150" data-expected-height="350">
    73130    <div class="sizedToGridArea negativeStartPositionGrowGridInRowDirection" data-offset-x="0" data-offset-y="150" data-expected-width="50" data-expected-height="200"></div>
    74131</div>
     
    88145
    89146<div style="position: relative">
     147<div class="grid" data-expected-width="550" data-expected-height="150">
     148    <div class="sizedToGridArea namedEndSpanGrowGridInColumnDirection" data-offset-x="50" data-offset-y="0" data-expected-width="500" data-expected-height="50"></div>
     149</div>
     150</div>
     151
     152<div style="position: relative">
     153<div class="grid" data-expected-width="150" data-expected-height="550">
     154    <div class="sizedToGridArea namedEndSpanGrowGridInRowDirection" data-offset-x="0" data-offset-y="50" data-expected-width="50" data-expected-height="500"></div>
     155</div>
     156</div>
     157
     158<div style="position: relative">
    90159<div class="grid" data-expected-width="150" data-expected-height="150">
    91160    <div class="sizedToGridArea negativeEndPositionStartSpanInColumnDirection" data-offset-x="50" data-offset-y="0" data-expected-width="100" data-expected-height="50"></div>
     
    101170<div style="position: relative">
    102171<div class="grid" data-expected-width="150" data-expected-height="150">
     172    <div class="sizedToGridArea negativeNamedGridLineEndPositionStartSpanInColumnDirection" data-offset-x="50" data-offset-y="0" data-expected-width="100" data-expected-height="50"></div>
     173</div>
     174</div>
     175
     176<div style="position: relative">
     177<div class="grid" data-expected-width="150" data-expected-height="150">
     178    <div class="sizedToGridArea negativeNamedGridLineEndPositionStartSpanInRowDirection" data-offset-x="0" data-offset-y="0" data-expected-width="50" data-expected-height="150"></div>
     179</div>
     180</div>
     181
     182<div style="position: relative">
     183<div class="grid" data-expected-width="150" data-expected-height="150">
    103184    <div class="sizedToGridArea negativeEndPositionStartNegativeInColumnDirection" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="50"></div>
    104185</div>
     
    111192</div>
    112193
     194<div style="position: relative">
     195<div class="grid" data-expected-width="150" data-expected-height="150">
     196    <div class="sizedToGridArea namedGridLineEndPositionStartNegativeInColumnDirection" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="50"></div>
     197</div>
     198</div>
     199
     200<div style="position: relative">
     201<div class="grid" data-expected-width="150" data-expected-height="150">
     202    <div class="sizedToGridArea namedGridLineEndPositionStartNegativeInRowDirection" data-offset-x="0" data-offset-y="0" data-expected-width="50" data-expected-height="50"></div>
     203</div>
     204</div>
    113205
    114206</body>
  • trunk/Source/WebCore/ChangeLog

    r155179 r155181  
     12013-09-06  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [CSS Grid Layout] Resolve named grid lines
     4        https://bugs.webkit.org/show_bug.cgi?id=119632
     5
     6        Reviewed by Andreas Kling.
     7
     8        From Blink r152659, r153794 by <jchaffraix@chromium.org>
     9
     10        Test: fast/css-grid-layout/grid-item-named-grid-line-resolution.html
     11
     12        This change adds the code which translates from a raw named grid
     13        line (stored in RenderStyle) to its actual grid position. This
     14        even includes named grid resolution for grid lines with the 'span'
     15        keyword.
     16
     17        * rendering/RenderGrid.cpp:
     18        (WebCore::RenderGrid::explicitGridSizeForSide):
     19        (WebCore::adjustGridPositionForRowEndColumnEndSide):
     20        (WebCore::adjustGridPositionForSide):
     21        (WebCore::RenderGrid::resolveNamedGridLinePositionFromStyle):
     22        (WebCore::RenderGrid::resolveGridPositionFromStyle):
     23        (WebCore::RenderGrid::resolveGridPositionAgainstOppositePosition):
     24        (WebCore::RenderGrid::resolveNamedGridLinePositionAgainstOppositePosition):
     25        (WebCore::RenderGrid::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition):
     26        (WebCore::RenderGrid::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):
     27        * rendering/RenderGrid.h:
     28
    1292013-09-06  Dirk Schulze  <krit@webkit.org>
    230
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r154996 r155181  
    338338}
    339339
     340size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const
     341{
     342    return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColumnCount() : explicitGridRowCount();
     343}
     344
    340345size_t RenderGrid::maximumIndexInDirection(TrackSizingDirection direction) const
    341346{
     
    754759}
    755760
     761inline static size_t adjustGridPositionForRowEndColumnEndSide(size_t resolvedPosition)
     762{
     763    return resolvedPosition ? resolvedPosition - 1 : 0;
     764}
     765
    756766static size_t adjustGridPositionForSide(size_t resolvedPosition, RenderGrid::GridPositionSide side)
    757767{
    758768    // An item finishing on the N-th line belongs to the N-1-th cell.
    759769    if (side == RenderGrid::ColumnEndSide || side == RenderGrid::RowEndSide)
    760         return resolvedPosition ? resolvedPosition - 1 : 0;
     770        return adjustGridPositionForRowEndColumnEndSide(resolvedPosition);
    761771
    762772    return resolvedPosition;
     773}
     774
     775size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& position, GridPositionSide side) const
     776{
     777    ASSERT(!position.namedGridLine().isNull());
     778
     779    const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
     780    NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
     781    if (it == gridLinesNames.end()) {
     782        if (position.isPositive())
     783            return 0;
     784        const size_t lastLine = explicitGridSizeForSide(side);
     785        return adjustGridPositionForSide(lastLine, side);
     786    }
     787
     788    size_t namedGridLineIndex;
     789    if (position.isPositive())
     790        namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->value.size()) - 1;
     791    else
     792        namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integerPosition()), 0);
     793    return adjustGridPositionForSide(it->value[namedGridLineIndex], side);
    763794}
    764795
     
    769800    case ExplicitPosition: {
    770801        ASSERT(position.integerPosition());
     802
     803        if (!position.namedGridLine().isNull())
     804            return resolveNamedGridLinePositionFromStyle(position, side);
     805
     806        // Handle <integer> explicit position.
    771807        if (position.isPositive())
    772808            return adjustGridPositionForSide(position.integerPosition() - 1, side);
    773809
    774810        size_t resolvedPosition = abs(position.integerPosition()) - 1;
    775         const size_t endOfTrack = (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColumnCount() : explicitGridRowCount();
     811        const size_t endOfTrack = explicitGridSizeForSide(side);
    776812
    777813        // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line.
     
    802838    ASSERT(position.spanPosition() > 0);
    803839
     840    if (!position.namedGridLine().isNull()) {
     841        // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
     842        return resolveNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, side);
     843    }
     844
    804845    // 'span 1' is contained inside a single grid track regardless of the direction.
    805846    // That's why the CSS span value is one more than the offset we apply.
     
    811852
    812853    return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition + positionOffset);
     854}
     855
     856PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
     857{
     858    ASSERT(position.isSpan());
     859    ASSERT(!position.namedGridLine().isNull());
     860    // Negative positions are not allowed per the specification and should have been handled during parsing.
     861    ASSERT(position.spanPosition() > 0);
     862
     863    const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
     864    NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
     865
     866    // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
     867    // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
     868    if (it == gridLinesNames.end())
     869        return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
     870
     871    if (side == RowStartSide || side == ColumnStartSide)
     872        return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
     873
     874    return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
     875}
     876
     877PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines) const
     878{
     879    // The grid line inequality needs to be strict (which doesn't match the after / end case) because |resolvedOppositePosition|
     880    // is already converted to an index in our grid representation (ie one was removed from the grid line to account for the side).
     881    // FIXME: This could be a binary search as |gridLines| is ordered.
     882    int firstLineBeforeOppositePositionIndex = gridLines.size() - 1;
     883    for (; firstLineBeforeOppositePositionIndex >= 0 && gridLines[firstLineBeforeOppositePositionIndex] > resolvedOppositePosition; --firstLineBeforeOppositePositionIndex) { }
     884
     885    size_t gridLineIndex = std::max<int>(0, firstLineBeforeOppositePositionIndex - position.spanPosition() + 1);
     886    size_t resolvedGridLinePosition = gridLines[gridLineIndex];
     887    if (resolvedGridLinePosition > resolvedOppositePosition)
     888        resolvedGridLinePosition = resolvedOppositePosition;
     889    return GridSpan::create(resolvedGridLinePosition, resolvedOppositePosition);
     890}
     891
     892PassOwnPtr<RenderGrid::GridSpan> RenderGrid::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines) const
     893{
     894    // FIXME: This could be a binary search as |gridLines| is ordered.
     895    size_t firstLineAfterOppositePositionIndex = 0;
     896    for (; firstLineAfterOppositePositionIndex < gridLines.size() && gridLines[firstLineAfterOppositePositionIndex] <= resolvedOppositePosition; ++firstLineAfterOppositePositionIndex) { }
     897
     898    size_t gridLineIndex = std::min(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
     899    size_t resolvedGridLinePosition = adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]);
     900    if (resolvedGridLinePosition < resolvedOppositePosition)
     901        resolvedGridLinePosition = resolvedOppositePosition;
     902    return GridSpan::create(resolvedOppositePosition, resolvedGridLinePosition);
    813903}
    814904
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r154753 r155181  
    125125    size_t explicitGridColumnCount() const;
    126126    size_t explicitGridRowCount() const;
     127    size_t explicitGridSizeForSide(GridPositionSide) const;
    127128    size_t maximumIndexInDirection(TrackSizingDirection) const;
    128129
     
    135136    GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, TrackSizingDirection, size_t) const;
    136137    PassOwnPtr<GridSpan> resolveGridPositionsFromStyle(const RenderBox*, TrackSizingDirection) const;
     138    size_t resolveNamedGridLinePositionFromStyle(const GridPosition&, GridPositionSide) const;
    137139    size_t resolveGridPositionFromStyle(const GridPosition&, GridPositionSide) const;
    138140    PassOwnPtr<GridSpan> resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, GridPositionSide) const;
     141    PassOwnPtr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, GridPositionSide) const;
     142    PassOwnPtr<GridSpan> resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, const Vector<size_t>&) const;
     143    PassOwnPtr<GridSpan> resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, const Vector<size_t>&) const;
    139144
    140145    LayoutUnit gridAreaBreadthForChild(const RenderBox* child, TrackSizingDirection, const Vector<GridTrack>&) const;
Note: See TracChangeset for help on using the changeset viewer.