Changeset 200368 in webkit


Ignore:
Timestamp:
May 3, 2016 4:30:29 AM (8 years ago)
Author:
svillar@igalia.com
Message:

[css-grid] Add support for position resolution with auto-repeat tracks
https://bugs.webkit.org/show_bug.cgi?id=157260

Reviewed by Darin Adler.

This is a generalization of our position resolution code so it now supports every possible
type of resolution (definite position, position spans, automatic resolution, named lines
resolution, grid areas...) under the presence of auto-repeat tracks, i.e., tracks that are
dynamically created by the LayoutGrid depending on the available space and that cannot be
directly inferred from the CSS declarations.

This means that we need two extra things to resolve positions:

  • the LayoutGrid needs to provide the number of auto-repeat tracks per axis
  • a wrapper is needed to hide the eventual presence of auto-repeat tracks (with their line

names) from the rest of the resolution code which should remain mostly unchanged.

The former is trivial (requires passing a new argument to some functions at the most) but
the latter requires a new class called NamedLineCollection. This class allow us to locate
and resolve named lines without having to insert the auto-repeat named lines in the already
existing data structures. It does it in a very compact representation as it does not
duplicate the names for every single repetition.

No new tests required as there is no change in behavior because the auto-repeat tracks
computation is not implemented yet. Current tests already test this code extensively, and
the auto-repeat code paths will be tested later once
RenderGrid::computeAutoRepeatTracksCount() is implemented.

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::computeAutoRepeatTracksCount): New method with empty implementation.
(WebCore::RenderGrid::placeItemsOnGrid): Initialize the auto repeat tracks count.
(WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
(WebCore::RenderGrid::offsetAndBreadthForPositionedChild):

  • rendering/RenderGrid.h:
  • rendering/style/GridPositionsResolver.cpp:

(WebCore::directionFromSide):
(WebCore::NamedLineCollection::NamedLineCollection): New class which is able to resolve the
positions of a given named line in the presence of auto-repeat and "normal" tracks.
(WebCore::NamedLineCollection::isValidNamedLineOrArea): Checks whether the given named line
is a valid line name or area.
(WebCore::NamedLineCollection::hasNamedLines): Checks whether the named line exists in the
given axis (either specified by auto-repeat or "normal" tracks).
(WebCore::NamedLineCollection::find): Looks for a line number whithin the line numbers where
the given named line was found.
(WebCore::NamedLineCollection::contains):
(WebCore::NamedLineCollection::firstPosition): Returns the first line where the given named
line is located.
(WebCore::adjustGridPositionsFromStyle): Use NamedLineCollection.
(WebCore::GridPositionsResolver::explicitGridColumnCount): Include auto repeat tracks.
(WebCore::GridPositionsResolver::explicitGridRowCount): Ditto.
(WebCore::explicitGridSizeForSide): Ditto.
(WebCore::lookAheadForNamedGridLine): Use NamedLineCollection.
(WebCore::lookBackForNamedGridLine): Ditto.
(WebCore::resolveNamedGridLinePositionFromStyle):
(WebCore::definiteGridSpanWithNamedLineSpanAgainstOpposite):
(WebCore::resolveNamedGridLinePositionAgainstOppositePosition):
(WebCore::resolveGridPositionAgainstOppositePosition):
(WebCore::resolveGridPositionFromStyle):
(WebCore::GridPositionsResolver::resolveGridPositionsFromStyle):
(WebCore::gridLinesForSide): Deleted.
(WebCore::GridPositionsResolver::isNonExistentNamedLineOrArea): Deleted.

  • rendering/style/GridPositionsResolver.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r200365 r200368  
     12016-05-02  Sergio Villar Senin  <svillar@igalia.com>
     2
     3        [css-grid] Add support for position resolution with auto-repeat tracks
     4        https://bugs.webkit.org/show_bug.cgi?id=157260
     5
     6        Reviewed by Darin Adler.
     7
     8        This is a generalization of our position resolution code so it now supports every possible
     9        type of resolution (definite position, position spans, automatic resolution, named lines
     10        resolution, grid areas...) under the presence of auto-repeat tracks, i.e., tracks that are
     11        dynamically created by the LayoutGrid depending on the available space and that cannot be
     12        directly inferred from the CSS declarations.
     13
     14        This means that we need two extra things to resolve positions:
     15        - the LayoutGrid needs to provide the number of auto-repeat tracks per axis
     16        - a wrapper is needed to hide the eventual presence of auto-repeat tracks (with their line
     17        names) from the rest of the resolution code which should remain mostly unchanged.
     18
     19        The former is trivial (requires passing a new argument to some functions at the most) but
     20        the latter requires a new class called NamedLineCollection. This class allow us to locate
     21        and resolve named lines without having to insert the auto-repeat named lines in the already
     22        existing data structures. It does it in a very compact representation as it does not
     23        duplicate the names for every single repetition.
     24
     25        No new tests required as there is no change in behavior because the auto-repeat tracks
     26        computation is not implemented yet. Current tests already test this code extensively, and
     27        the auto-repeat code paths will be tested later once
     28        RenderGrid::computeAutoRepeatTracksCount() is implemented.
     29
     30        * rendering/RenderGrid.cpp:
     31        (WebCore::RenderGrid::computeAutoRepeatTracksCount): New method with empty implementation.
     32        (WebCore::RenderGrid::placeItemsOnGrid): Initialize the auto repeat tracks count.
     33        (WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
     34        (WebCore::RenderGrid::offsetAndBreadthForPositionedChild):
     35        * rendering/RenderGrid.h:
     36        * rendering/style/GridPositionsResolver.cpp:
     37        (WebCore::directionFromSide):
     38        (WebCore::NamedLineCollection::NamedLineCollection): New class which is able to resolve the
     39        positions of a given named line in the presence of auto-repeat and "normal" tracks.
     40        (WebCore::NamedLineCollection::isValidNamedLineOrArea): Checks whether the given named line
     41        is a valid line name or area.
     42        (WebCore::NamedLineCollection::hasNamedLines): Checks whether the named line exists in the
     43        given axis (either specified by auto-repeat or "normal" tracks).
     44        (WebCore::NamedLineCollection::find): Looks for a line number whithin the line numbers where
     45        the given named line was found.
     46        (WebCore::NamedLineCollection::contains):
     47        (WebCore::NamedLineCollection::firstPosition): Returns the first line where the given named
     48        line is located.
     49        (WebCore::adjustGridPositionsFromStyle): Use NamedLineCollection.
     50        (WebCore::GridPositionsResolver::explicitGridColumnCount): Include auto repeat tracks.
     51        (WebCore::GridPositionsResolver::explicitGridRowCount): Ditto.
     52        (WebCore::explicitGridSizeForSide): Ditto.
     53        (WebCore::lookAheadForNamedGridLine): Use NamedLineCollection.
     54        (WebCore::lookBackForNamedGridLine): Ditto.
     55        (WebCore::resolveNamedGridLinePositionFromStyle):
     56        (WebCore::definiteGridSpanWithNamedLineSpanAgainstOpposite):
     57        (WebCore::resolveNamedGridLinePositionAgainstOppositePosition):
     58        (WebCore::resolveGridPositionAgainstOppositePosition):
     59        (WebCore::resolveGridPositionFromStyle):
     60        (WebCore::GridPositionsResolver::resolveGridPositionsFromStyle):
     61        (WebCore::gridLinesForSide): Deleted.
     62        (WebCore::GridPositionsResolver::isNonExistentNamedLineOrArea): Deleted.
     63        * rendering/style/GridPositionsResolver.h:
     64
    1652016-05-03  Carlos Garcia Campos  <cgarcia@igalia.com>
    266
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r200181 r200368  
    11861186}
    11871187
     1188unsigned RenderGrid::computeAutoRepeatTracksCount(GridTrackSizingDirection) const
     1189{
     1190    // FIXME: implement the algorithm to compute the number of auto repeat tracks.
     1191    return 0;
     1192}
     1193
    11881194void RenderGrid::placeItemsOnGrid()
    11891195{
    11901196    ASSERT(!gridWasPopulated());
    11911197    ASSERT(m_gridItemArea.isEmpty());
     1198
     1199    m_autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns);
     1200    m_autoRepeatRows = computeAutoRepeatTracksCount(ForRows);
    11921201
    11931202    populateExplicitGridAndOrderIterator();
     
    12181227    }
    12191228
    1220     ASSERT(gridRowCount() >= GridPositionsResolver::explicitGridRowCount(style()));
    1221     ASSERT(gridColumnCount() >= GridPositionsResolver::explicitGridColumnCount(style()));
     1229    ASSERT(gridRowCount() >= GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));
     1230    ASSERT(gridColumnCount() >= GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));
    12221231
    12231232    placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems);
     
    12391248    OrderIteratorPopulator populator(m_orderIterator);
    12401249    m_smallestRowStart = m_smallestColumnStart = 0;
    1241     unsigned maximumRowIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridRowCount(style()));
    1242     unsigned maximumColumnIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridColumnCount(style()));
     1250    unsigned maximumRowIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));
     1251    unsigned maximumColumnIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));
    12431252
    12441253    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
     
    12481257        populator.collectChild(*child);
    12491258
    1250         GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForRows);
     1259        GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForRows, m_autoRepeatRows);
    12511260        if (!rowPositions.isIndefinite()) {
    12521261            m_smallestRowStart = std::min(m_smallestRowStart, rowPositions.untranslatedStartLine());
     
    12581267        }
    12591268
    1260         GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForColumns);
     1269        GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForColumns, m_autoRepeatColumns);
    12611270        if (!columnPositions.isIndefinite()) {
    12621271            m_smallestColumnStart = std::min(m_smallestColumnStart, columnPositions.untranslatedStartLine());
     
    15221531    bool isRowAxis = direction == ForColumns;
    15231532
    1524     GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), child, direction);
     1533    unsigned autoRepeatCount = autoRepeatCountForDirection(direction);
     1534    GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), child, direction, autoRepeatCount);
    15251535    if (positions.isIndefinite()) {
    15261536        offset = LayoutUnit();
     
    15371547    GridPosition endPosition = isRowAxis ? child.style().gridItemColumnEnd() : child.style().gridItemRowEnd();
    15381548    int firstExplicitLine = smallestStart;
    1539     int lastExplicitLine = (isRowAxis ? GridPositionsResolver::explicitGridColumnCount(style()) : GridPositionsResolver::explicitGridRowCount(style())) + smallestStart;
     1549    int lastExplicitLine = (isRowAxis ? GridPositionsResolver::explicitGridColumnCount(style(), autoRepeatCount) : GridPositionsResolver::explicitGridRowCount(style(), autoRepeatCount)) + smallestStart;
    15401550
    15411551    bool startIsAuto = startPosition.isAuto()
    1542         || (startPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(startPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnStartSide : RowStartSide))
     1552        || (startPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(startPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnStartSide : RowStartSide))
    15431553        || (startLine < firstExplicitLine)
    15441554        || (startLine > lastExplicitLine);
    15451555    bool endIsAuto = endPosition.isAuto()
    1546         || (endPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(endPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnEndSide : RowEndSide))
     1556        || (endPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(endPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnEndSide : RowEndSide))
    15471557        || (endLine < firstExplicitLine)
    15481558        || (endLine > lastExplicitLine);
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r200041 r200368  
    6464    LayoutUnit offsetBetweenTracks(GridTrackSizingDirection) const;
    6565
     66    size_t autoRepeatCountForDirection(GridTrackSizingDirection) const;
     67
    6668private:
    6769    const char* renderName() const override;
     
    8082    void ensureGridSize(unsigned maximumRowSize, unsigned maximumColumnSize);
    8183    void insertItemIntoGrid(RenderBox&, const GridArea&);
     84
     85    unsigned computeAutoRepeatTracksCount(GridTrackSizingDirection) const;
     86
    8287    void placeItemsOnGrid();
    8388    void populateExplicitGridAndOrderIterator();
     
    199204    int m_smallestColumnStart;
    200205    int m_smallestRowStart;
     206
     207    unsigned m_autoRepeatColumns { 0 };
     208    unsigned m_autoRepeatRows { 0 };
    201209};
    202210
     211size_t inline RenderGrid::autoRepeatCountForDirection(GridTrackSizingDirection direction) const
     212{
     213    return direction == ForColumns ? m_autoRepeatColumns : m_autoRepeatRows;
     214}
     215
    203216} // namespace WebCore
    204217
  • trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp

    r199661 r200368  
    6060}
    6161
    62 static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
    63 {
    64     return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines();
     62static inline GridTrackSizingDirection directionFromSide(GridPositionSide side)
     63{
     64    return side == ColumnStartSide || side == ColumnEndSide ? ForColumns : ForRows;
    6565}
    6666
     
    7070}
    7171
    72 bool GridPositionsResolver::isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle& style, GridPositionSide side)
    73 {
    74     const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side);
    75     return !gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) && !gridLineNames.contains(lineName);
     72NamedLineCollection::NamedLineCollection(const RenderStyle& gridContainerStyle, const String& namedLine, GridTrackSizingDirection direction, unsigned lastLine, unsigned autoRepeatTracksCount)
     73    : m_lastLine(lastLine)
     74    , m_repetitions(autoRepeatTracksCount)
     75{
     76    bool isRowAxis = direction == ForColumns;
     77    const NamedGridLinesMap& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
     78    const NamedGridLinesMap& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines();
     79
     80    auto linesIterator = gridLineNames.find(namedLine);
     81    m_namedLinesIndexes = linesIterator == gridLineNames.end() ? nullptr : &linesIterator->value;
     82
     83    auto autoRepeatLinesIterator = autoRepeatGridLineNames.find(namedLine);
     84    m_autoRepeatNamedLinesIndexes = autoRepeatLinesIterator == autoRepeatGridLineNames.end() ? nullptr : &autoRepeatLinesIterator->value;
     85
     86    m_insertionPoint = isRowAxis ? gridContainerStyle.gridAutoRepeatColumnsInsertionPoint() : gridContainerStyle.gridAutoRepeatRowsInsertionPoint();
     87}
     88
     89bool NamedLineCollection::isValidNamedLineOrArea(const String& namedLine, const RenderStyle& gridContainerStyle, GridPositionSide side)
     90{
     91    bool isRowAxis = directionFromSide(side) == ForColumns;
     92    auto& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
     93    auto& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines();
     94
     95    if (gridLineNames.contains(namedLine) || autoRepeatGridLineNames.contains(namedLine))
     96        return true;
     97
     98    String implicitName = implicitNamedGridLineForSide(namedLine, side);
     99    return gridLineNames.contains(implicitName) || autoRepeatGridLineNames.contains(implicitName);
     100}
     101
     102bool NamedLineCollection::hasNamedLines() const
     103{
     104    return m_namedLinesIndexes || m_autoRepeatNamedLinesIndexes;
     105}
     106
     107size_t NamedLineCollection::find(unsigned line) const
     108{
     109    if (line > m_lastLine)
     110        return notFound;
     111
     112    if (!m_autoRepeatNamedLinesIndexes || line < m_insertionPoint)
     113        return m_namedLinesIndexes ? m_namedLinesIndexes->find(line) : notFound;
     114
     115    if (line <= (m_insertionPoint + m_repetitions)) {
     116        size_t localIndex = line - m_insertionPoint;
     117
     118        // The line names defined in the last line are also present in the first line of the next
     119        // repetition (if any). Same for the line names defined in the first line. Note that there
     120        // is only one auto-repeated track allowed by the syntax, that's why it's enough to store
     121        // indexes 0 and 1 (before and after the track size).
     122        if (localIndex == m_repetitions)
     123            return m_autoRepeatNamedLinesIndexes->find(1u);
     124        size_t position = m_autoRepeatNamedLinesIndexes->find(0u);
     125        if (position != notFound)
     126            return position;
     127        return localIndex ? m_autoRepeatNamedLinesIndexes->find(1u) : notFound;
     128    }
     129
     130    return m_namedLinesIndexes ? m_namedLinesIndexes->find(line - (m_repetitions - 1)) : notFound;
     131}
     132
     133bool NamedLineCollection::contains(unsigned line) const
     134{
     135    ASSERT(hasNamedLines());
     136    return find(line) != notFound;
     137}
     138
     139unsigned NamedLineCollection::firstPosition() const
     140{
     141    ASSERT(hasNamedLines());
     142    unsigned firstLine = 0;
     143
     144    if (!m_autoRepeatNamedLinesIndexes) {
     145        if (!m_insertionPoint || m_insertionPoint < m_namedLinesIndexes->at(firstLine))
     146            return m_namedLinesIndexes->at(firstLine) + (m_repetitions ? m_repetitions - 1 : 0);
     147        return m_namedLinesIndexes->at(firstLine);
     148    }
     149
     150    if (!m_namedLinesIndexes)
     151        return m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint;
     152
     153    if (!m_insertionPoint)
     154        return m_autoRepeatNamedLinesIndexes->at(firstLine);
     155
     156    return std::min(m_namedLinesIndexes->at(firstLine), m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint);
    76157}
    77158
     
    89170    if (gridItem.isOutOfFlowPositioned()) {
    90171        // Early detect the case of non existing named grid lines for positioned items.
    91         if (initialPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction)))
     172        if (initialPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction)))
    92173            initialPosition.setAutoPosition();
    93174
    94         if (finalPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction)))
     175        if (finalPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction)))
    95176            finalPosition.setAutoPosition();
    96177    }
     
    103184}
    104185
    105 unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
    106 {
    107     return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size(), gridContainerStyle.namedGridAreaColumnCount()), kGridMaxTracks);
    108 }
    109 
    110 unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle)
    111 {
    112     return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size(), gridContainerStyle.namedGridAreaRowCount()), kGridMaxTracks);
    113 }
    114 
    115 static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
    116 {
    117     return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle);
    118 }
    119 
    120 static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, const Vector<unsigned>* namedGridLinesIndexes, unsigned gridLastLine)
     186unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
     187{
     188    return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaColumnCount()), kGridMaxTracks);
     189}
     190
     191unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
     192{
     193    return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaRowCount()), kGridMaxTracks);
     194}
     195
     196static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side, unsigned autoRepeatTracksCount)
     197{
     198    return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle, autoRepeatTracksCount) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle, autoRepeatTracksCount);
     199}
     200
     201static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, unsigned gridLastLine, NamedLineCollection& linesCollection)
    121202{
    122203    ASSERT(numberOfLines);
     
    126207    unsigned end = std::max(start, 0);
    127208
    128     if (!namedGridLinesIndexes)
     209    if (!linesCollection.hasNamedLines())
    129210        return std::max(end, gridLastLine + 1) + numberOfLines - 1;
    130211
    131212    for (; numberOfLines; ++end) {
    132         if (end > gridLastLine || namedGridLinesIndexes->contains(end))
     213        if (end > gridLastLine || linesCollection.contains(end))
    133214            numberOfLines--;
    134215    }
     
    138219}
    139220
    140 static int lookBackForNamedGridLine(int end, unsigned numberOfLines, const Vector<unsigned>* namedGridLinesIndexes, int gridLastLine)
     221static int lookBackForNamedGridLine(int end, unsigned numberOfLines, int gridLastLine, NamedLineCollection& linesCollection)
    141222{
    142223    ASSERT(numberOfLines);
     
    146227    int start = std::min(end, gridLastLine);
    147228
    148     if (!namedGridLinesIndexes)
     229    if (!linesCollection.hasNamedLines())
    149230        return std::min(start, -1) - numberOfLines + 1;
    150231
    151232    for (; numberOfLines; --start) {
    152         if (start < 0 || namedGridLinesIndexes->contains(static_cast<size_t>(start)))
     233        if (start < 0 || linesCollection.contains(start))
    153234            numberOfLines--;
    154235    }
     
    157238}
    158239
    159 static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
     240static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
    160241{
    161242    ASSERT(!position.namedGridLine().isNull());
    162243
    163     const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
    164     auto iterator = gridLinesNames.find(position.namedGridLine());
    165     const Vector<unsigned>* gridLines = iterator == gridLinesNames.end() ? nullptr : &iterator->value;
    166     unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
     244    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
     245    NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
     246
    167247    if (position.isPositive())
    168         return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), gridLines, lastLine);
    169     return lookBackForNamedGridLine(lastLine, std::abs(position.integerPosition()), gridLines, lastLine);
    170 }
    171 
    172 static GridSpan definiteGridSpanWithNamedLineSpanAgainstOpposite(int oppositeLine, const GridPosition& position, GridPositionSide side, const Vector<unsigned>* gridLines, unsigned lastLine)
     248        return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), lastLine, linesCollection);
     249    return lookBackForNamedGridLine(lastLine, std::abs(position.integerPosition()), lastLine, linesCollection);
     250}
     251
     252static GridSpan definiteGridSpanWithNamedLineSpanAgainstOpposite(int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned lastLine, NamedLineCollection& linesCollection)
    173253{
    174254    int start, end;
    175 
    176255    if (side == RowStartSide || side == ColumnStartSide) {
    177         start = lookBackForNamedGridLine(oppositeLine - 1, position.spanPosition(), gridLines, lastLine);
     256        start = lookBackForNamedGridLine(oppositeLine - 1, position.spanPosition(), lastLine, linesCollection);
    178257        end = oppositeLine;
    179258    } else {
    180259        start = oppositeLine;
    181         end = lookAheadForNamedGridLine(oppositeLine + 1, position.spanPosition(), gridLines, lastLine);
     260        end = lookAheadForNamedGridLine(oppositeLine + 1, position.spanPosition(), lastLine, linesCollection);
    182261    }
    183262
     
    185264}
    186265
    187 static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side)
     266static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
    188267{
    189268    ASSERT(position.isSpan());
     
    192271    ASSERT(position.spanPosition() > 0);
    193272
    194     const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
    195     auto iterator = gridLinesNames.find(position.namedGridLine());
    196     const Vector<unsigned>* gridLines = iterator == gridLinesNames.end() ? nullptr : &iterator->value;
    197     unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
    198 
    199     return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, gridLines, lastLine);
    200 }
    201 
    202 static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side)
     273    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
     274    NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
     275    return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, lastLine, linesCollection);
     276}
     277
     278static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
    203279{
    204280    if (position.isAuto()) {
     
    213289    if (!position.namedGridLine().isNull()) {
    214290        // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
    215         return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side);
     291        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side, autoRepeatTracksCount);
    216292    }
    217293
     
    243319}
    244320
    245 static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
     321static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
    246322{
    247323    switch (position.type()) {
     
    250326
    251327        if (!position.namedGridLine().isNull())
    252             return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side);
     328            return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side, autoRepeatTracksCount);
    253329
    254330        // Handle <integer> explicit position.
     
    257333
    258334        unsigned resolvedPosition = std::abs(position.integerPosition()) - 1;
    259         const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side);
     335        const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
    260336
    261337        return endOfTrack - resolvedPosition;
     
    269345        ASSERT(!position.namedGridLine().isNull());
    270346
    271         const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side);
    272         auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
    273         if (implicitLine != gridLineNames.end())
    274             return implicitLine->value[0];
     347        unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
     348        NamedLineCollection implicitLines(gridContainerStyle, implicitNamedGridLineForSide(namedGridLine, side), directionFromSide(side), lastLine, autoRepeatTracksCount);
     349        if (implicitLines.hasNamedLines())
     350            return implicitLines.firstPosition();
    275351
    276352        // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
    277353        // item's placement.
    278         auto explicitLine = gridLineNames.find(namedGridLine);
    279         if (explicitLine != gridLineNames.end())
    280             return explicitLine->value[0];
    281 
    282         ASSERT(GridPositionsResolver::isNonExistentNamedLineOrArea(namedGridLine, gridContainerStyle, side));
     354        NamedLineCollection explicitLines(gridContainerStyle, namedGridLine, directionFromSide(side), lastLine, autoRepeatTracksCount);
     355        if (explicitLines.hasNamedLines())
     356            return explicitLines.firstPosition();
     357
     358        ASSERT(!NamedLineCollection::isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side));
    283359        // If none of the above works specs mandate to assume that all the lines in the implicit grid have this name.
    284         unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
    285360        return lastLine + 1;
    286361    }
     
    295370}
    296371
    297 GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction)
     372GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, unsigned autoRepeatTracksCount)
    298373{
    299374    GridPosition initialPosition, finalPosition;
     
    309384    if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
    310385        // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
    311         auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide);
    312         return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide);
     386        auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
     387        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide, autoRepeatTracksCount);
    313388    }
    314389
    315390    if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
    316391        // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
    317         auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide);
    318         return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide);
    319     }
    320 
    321     int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide);
    322     int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide);
     392        auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
     393        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide, autoRepeatTracksCount);
     394    }
     395
     396    int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
     397    int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
    323398
    324399    if (startLine > endLine)
  • trunk/Source/WebCore/rendering/style/GridPositionsResolver.h

    r198207 r200368  
    4747};
    4848
     49class NamedLineCollection {
     50    WTF_MAKE_NONCOPYABLE(NamedLineCollection);
     51public:
     52    NamedLineCollection(const RenderStyle&, const String& namedLine, GridTrackSizingDirection, unsigned lastLine, unsigned autoRepeatTracksCount);
     53
     54    static bool isValidNamedLineOrArea(const String& namedLine, const RenderStyle&, GridPositionSide);
     55
     56    bool hasNamedLines() const;
     57    unsigned firstPosition() const;
     58
     59    bool contains(unsigned line) const;
     60
     61private:
     62    size_t find(unsigned line) const;
     63
     64    const Vector<unsigned>* m_namedLinesIndexes { nullptr };
     65    const Vector<unsigned>* m_autoRepeatNamedLinesIndexes { nullptr };
     66
     67    unsigned m_insertionPoint;
     68    unsigned m_lastLine;
     69    unsigned m_repetitions;
     70};
     71
    4972// Class with all the code related to grid items positions resolution.
    5073class GridPositionsResolver {
    5174public:
    5275    static unsigned spanSizeForAutoPlacedItem(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
    53     static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
    54     static unsigned explicitGridColumnCount(const RenderStyle&);
    55     static unsigned explicitGridRowCount(const RenderStyle&);
    56     static bool isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle&, GridPositionSide);
     76    static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, unsigned autoRepeatTracksCount);
     77    static unsigned explicitGridColumnCount(const RenderStyle&, unsigned autoRepeatColumnsCount);
     78    static unsigned explicitGridRowCount(const RenderStyle&, unsigned autoRepeatRowsCount);
    5779};
    5880
Note: See TracChangeset for help on using the changeset viewer.