Title: [200368] trunk/Source/WebCore
Revision
200368
Author
[email protected]
Date
2016-05-03 04:30:29 -0700 (Tue, 03 May 2016)

Log 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:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (200367 => 200368)


--- trunk/Source/WebCore/ChangeLog	2016-05-03 09:18:40 UTC (rev 200367)
+++ trunk/Source/WebCore/ChangeLog	2016-05-03 11:30:29 UTC (rev 200368)
@@ -1,3 +1,67 @@
+2016-05-02  Sergio Villar Senin  <[email protected]>
+
+        [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:
+
 2016-05-03  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Fix GObject DOM bindings API break after r200316.

Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (200367 => 200368)


--- trunk/Source/WebCore/rendering/RenderGrid.cpp	2016-05-03 09:18:40 UTC (rev 200367)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp	2016-05-03 11:30:29 UTC (rev 200368)
@@ -1185,11 +1185,20 @@
     }
 }
 
+unsigned RenderGrid::computeAutoRepeatTracksCount(GridTrackSizingDirection) const
+{
+    // FIXME: implement the algorithm to compute the number of auto repeat tracks.
+    return 0;
+}
+
 void RenderGrid::placeItemsOnGrid()
 {
     ASSERT(!gridWasPopulated());
     ASSERT(m_gridItemArea.isEmpty());
 
+    m_autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns);
+    m_autoRepeatRows = computeAutoRepeatTracksCount(ForRows);
+
     populateExplicitGridAndOrderIterator();
 
     Vector<RenderBox*> autoMajorAxisAutoGridItems;
@@ -1217,8 +1226,8 @@
         insertItemIntoGrid(*child, GridArea(area.rows, area.columns));
     }
 
-    ASSERT(gridRowCount() >= GridPositionsResolver::explicitGridRowCount(style()));
-    ASSERT(gridColumnCount() >= GridPositionsResolver::explicitGridColumnCount(style()));
+    ASSERT(gridRowCount() >= GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));
+    ASSERT(gridColumnCount() >= GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));
 
     placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems);
     placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems);
@@ -1238,8 +1247,8 @@
 {
     OrderIteratorPopulator populator(m_orderIterator);
     m_smallestRowStart = m_smallestColumnStart = 0;
-    unsigned maximumRowIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridRowCount(style()));
-    unsigned maximumColumnIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridColumnCount(style()));
+    unsigned maximumRowIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));
+    unsigned maximumColumnIndex = std::max<unsigned>(1, GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));
 
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
         if (child->isOutOfFlowPositioned())
@@ -1247,7 +1256,7 @@
 
         populator.collectChild(*child);
 
-        GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForRows);
+        GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForRows, m_autoRepeatRows);
         if (!rowPositions.isIndefinite()) {
             m_smallestRowStart = std::min(m_smallestRowStart, rowPositions.untranslatedStartLine());
             maximumRowIndex = std::max<int>(maximumRowIndex, rowPositions.untranslatedEndLine());
@@ -1257,7 +1266,7 @@
             maximumRowIndex = std::max(maximumRowIndex, spanSize);
         }
 
-        GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForColumns);
+        GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForColumns, m_autoRepeatColumns);
         if (!columnPositions.isIndefinite()) {
             m_smallestColumnStart = std::min(m_smallestColumnStart, columnPositions.untranslatedStartLine());
             maximumColumnIndex = std::max<int>(maximumColumnIndex, columnPositions.untranslatedEndLine());
@@ -1521,7 +1530,8 @@
     ASSERT(child.isHorizontalWritingMode() == isHorizontalWritingMode());
     bool isRowAxis = direction == ForColumns;
 
-    GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), child, direction);
+    unsigned autoRepeatCount = autoRepeatCountForDirection(direction);
+    GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), child, direction, autoRepeatCount);
     if (positions.isIndefinite()) {
         offset = LayoutUnit();
         breadth = isRowAxis ? clientLogicalWidth() : clientLogicalHeight();
@@ -1536,14 +1546,14 @@
     GridPosition startPosition = isRowAxis ? child.style().gridItemColumnStart() : child.style().gridItemRowStart();
     GridPosition endPosition = isRowAxis ? child.style().gridItemColumnEnd() : child.style().gridItemRowEnd();
     int firstExplicitLine = smallestStart;
-    int lastExplicitLine = (isRowAxis ? GridPositionsResolver::explicitGridColumnCount(style()) : GridPositionsResolver::explicitGridRowCount(style())) + smallestStart;
+    int lastExplicitLine = (isRowAxis ? GridPositionsResolver::explicitGridColumnCount(style(), autoRepeatCount) : GridPositionsResolver::explicitGridRowCount(style(), autoRepeatCount)) + smallestStart;
 
     bool startIsAuto = startPosition.isAuto()
-        || (startPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(startPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnStartSide : RowStartSide))
+        || (startPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(startPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnStartSide : RowStartSide))
         || (startLine < firstExplicitLine)
         || (startLine > lastExplicitLine);
     bool endIsAuto = endPosition.isAuto()
-        || (endPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(endPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnEndSide : RowEndSide))
+        || (endPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(endPosition.namedGridLine(), style(), (direction == ForColumns) ? ColumnEndSide : RowEndSide))
         || (endLine < firstExplicitLine)
         || (endLine > lastExplicitLine);
 

Modified: trunk/Source/WebCore/rendering/RenderGrid.h (200367 => 200368)


--- trunk/Source/WebCore/rendering/RenderGrid.h	2016-05-03 09:18:40 UTC (rev 200367)
+++ trunk/Source/WebCore/rendering/RenderGrid.h	2016-05-03 11:30:29 UTC (rev 200368)
@@ -63,6 +63,8 @@
     LayoutUnit guttersSize(GridTrackSizingDirection, size_t span) const;
     LayoutUnit offsetBetweenTracks(GridTrackSizingDirection) const;
 
+    size_t autoRepeatCountForDirection(GridTrackSizingDirection) const;
+
 private:
     const char* renderName() const override;
     bool isRenderGrid() const override { return true; }
@@ -79,6 +81,9 @@
 
     void ensureGridSize(unsigned maximumRowSize, unsigned maximumColumnSize);
     void insertItemIntoGrid(RenderBox&, const GridArea&);
+
+    unsigned computeAutoRepeatTracksCount(GridTrackSizingDirection) const;
+
     void placeItemsOnGrid();
     void populateExplicitGridAndOrderIterator();
     std::unique_ptr<GridArea> createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox&, GridTrackSizingDirection, const GridSpan&) const;
@@ -198,8 +203,16 @@
 
     int m_smallestColumnStart;
     int m_smallestRowStart;
+
+    unsigned m_autoRepeatColumns { 0 };
+    unsigned m_autoRepeatRows { 0 };
 };
 
+size_t inline RenderGrid::autoRepeatCountForDirection(GridTrackSizingDirection direction) const
+{
+    return direction == ForColumns ? m_autoRepeatColumns : m_autoRepeatRows;
+}
+
 } // namespace WebCore
 
 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderGrid, isRenderGrid())

Modified: trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp (200367 => 200368)


--- trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp	2016-05-03 09:18:40 UTC (rev 200367)
+++ trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp	2016-05-03 11:30:29 UTC (rev 200368)
@@ -59,9 +59,9 @@
     return direction == ForColumns ? ColumnEndSide : RowEndSide;
 }
 
-static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
+static inline GridTrackSizingDirection directionFromSide(GridPositionSide side)
 {
-    return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines();
+    return side == ColumnStartSide || side == ColumnEndSide ? ForColumns : ForRows;
 }
 
 static const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side)
@@ -69,12 +69,93 @@
     return lineName + (isStartSide(side) ? "-start" : "-end");
 }
 
-bool GridPositionsResolver::isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle& style, GridPositionSide side)
+NamedLineCollection::NamedLineCollection(const RenderStyle& gridContainerStyle, const String& namedLine, GridTrackSizingDirection direction, unsigned lastLine, unsigned autoRepeatTracksCount)
+    : m_lastLine(lastLine)
+    , m_repetitions(autoRepeatTracksCount)
 {
-    const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side);
-    return !gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) && !gridLineNames.contains(lineName);
+    bool isRowAxis = direction == ForColumns;
+    const NamedGridLinesMap& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
+    const NamedGridLinesMap& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines();
+
+    auto linesIterator = gridLineNames.find(namedLine);
+    m_namedLinesIndexes = linesIterator == gridLineNames.end() ? nullptr : &linesIterator->value;
+
+    auto autoRepeatLinesIterator = autoRepeatGridLineNames.find(namedLine);
+    m_autoRepeatNamedLinesIndexes = autoRepeatLinesIterator == autoRepeatGridLineNames.end() ? nullptr : &autoRepeatLinesIterator->value;
+
+    m_insertionPoint = isRowAxis ? gridContainerStyle.gridAutoRepeatColumnsInsertionPoint() : gridContainerStyle.gridAutoRepeatRowsInsertionPoint();
 }
 
+bool NamedLineCollection::isValidNamedLineOrArea(const String& namedLine, const RenderStyle& gridContainerStyle, GridPositionSide side)
+{
+    bool isRowAxis = directionFromSide(side) == ForColumns;
+    auto& gridLineNames = isRowAxis ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
+    auto& autoRepeatGridLineNames = isRowAxis ? gridContainerStyle.autoRepeatNamedGridColumnLines() : gridContainerStyle.autoRepeatNamedGridRowLines();
+
+    if (gridLineNames.contains(namedLine) || autoRepeatGridLineNames.contains(namedLine))
+        return true;
+
+    String implicitName = implicitNamedGridLineForSide(namedLine, side);
+    return gridLineNames.contains(implicitName) || autoRepeatGridLineNames.contains(implicitName);
+}
+
+bool NamedLineCollection::hasNamedLines() const
+{
+    return m_namedLinesIndexes || m_autoRepeatNamedLinesIndexes;
+}
+
+size_t NamedLineCollection::find(unsigned line) const
+{
+    if (line > m_lastLine)
+        return notFound;
+
+    if (!m_autoRepeatNamedLinesIndexes || line < m_insertionPoint)
+        return m_namedLinesIndexes ? m_namedLinesIndexes->find(line) : notFound;
+
+    if (line <= (m_insertionPoint + m_repetitions)) {
+        size_t localIndex = line - m_insertionPoint;
+
+        // The line names defined in the last line are also present in the first line of the next
+        // repetition (if any). Same for the line names defined in the first line. Note that there
+        // is only one auto-repeated track allowed by the syntax, that's why it's enough to store
+        // indexes 0 and 1 (before and after the track size).
+        if (localIndex == m_repetitions)
+            return m_autoRepeatNamedLinesIndexes->find(1u);
+        size_t position = m_autoRepeatNamedLinesIndexes->find(0u);
+        if (position != notFound)
+            return position;
+        return localIndex ? m_autoRepeatNamedLinesIndexes->find(1u) : notFound;
+    }
+
+    return m_namedLinesIndexes ? m_namedLinesIndexes->find(line - (m_repetitions - 1)) : notFound;
+}
+
+bool NamedLineCollection::contains(unsigned line) const
+{
+    ASSERT(hasNamedLines());
+    return find(line) != notFound;
+}
+
+unsigned NamedLineCollection::firstPosition() const
+{
+    ASSERT(hasNamedLines());
+    unsigned firstLine = 0;
+
+    if (!m_autoRepeatNamedLinesIndexes) {
+        if (!m_insertionPoint || m_insertionPoint < m_namedLinesIndexes->at(firstLine))
+            return m_namedLinesIndexes->at(firstLine) + (m_repetitions ? m_repetitions - 1 : 0);
+        return m_namedLinesIndexes->at(firstLine);
+    }
+
+    if (!m_namedLinesIndexes)
+        return m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint;
+
+    if (!m_insertionPoint)
+        return m_autoRepeatNamedLinesIndexes->at(firstLine);
+
+    return std::min(m_namedLinesIndexes->at(firstLine), m_autoRepeatNamedLinesIndexes->at(firstLine) + m_insertionPoint);
+}
+
 static void adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition)
 {
     bool isForColumns = direction == ForColumns;
@@ -88,10 +169,10 @@
 
     if (gridItem.isOutOfFlowPositioned()) {
         // Early detect the case of non existing named grid lines for positioned items.
-        if (initialPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction)))
+        if (initialPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction)))
             initialPosition.setAutoPosition();
 
-        if (finalPosition.isNamedGridArea() && GridPositionsResolver::isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction)))
+        if (finalPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction)))
             finalPosition.setAutoPosition();
     }
 
@@ -102,22 +183,22 @@
         initialPosition.setSpanPosition(1, String());
 }
 
-unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
+unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
 {
-    return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size(), gridContainerStyle.namedGridAreaColumnCount()), kGridMaxTracks);
+    return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaColumnCount()), kGridMaxTracks);
 }
 
-unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle)
+unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
 {
-    return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size(), gridContainerStyle.namedGridAreaRowCount()), kGridMaxTracks);
+    return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaRowCount()), kGridMaxTracks);
 }
 
-static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
+static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side, unsigned autoRepeatTracksCount)
 {
-    return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle);
+    return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle, autoRepeatTracksCount) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle, autoRepeatTracksCount);
 }
 
-static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, const Vector<unsigned>* namedGridLinesIndexes, unsigned gridLastLine)
+static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, unsigned gridLastLine, NamedLineCollection& linesCollection)
 {
     ASSERT(numberOfLines);
 
@@ -125,11 +206,11 @@
     // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int
     unsigned end = std::max(start, 0);
 
-    if (!namedGridLinesIndexes)
+    if (!linesCollection.hasNamedLines())
         return std::max(end, gridLastLine + 1) + numberOfLines - 1;
 
     for (; numberOfLines; ++end) {
-        if (end > gridLastLine || namedGridLinesIndexes->contains(end))
+        if (end > gridLastLine || linesCollection.contains(end))
             numberOfLines--;
     }
 
@@ -137,7 +218,7 @@
     return end - 1;
 }
 
-static int lookBackForNamedGridLine(int end, unsigned numberOfLines, const Vector<unsigned>* namedGridLinesIndexes, int gridLastLine)
+static int lookBackForNamedGridLine(int end, unsigned numberOfLines, int gridLastLine, NamedLineCollection& linesCollection)
 {
     ASSERT(numberOfLines);
 
@@ -145,61 +226,56 @@
     // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int
     int start = std::min(end, gridLastLine);
 
-    if (!namedGridLinesIndexes)
+    if (!linesCollection.hasNamedLines())
         return std::min(start, -1) - numberOfLines + 1;
 
     for (; numberOfLines; --start) {
-        if (start < 0 || namedGridLinesIndexes->contains(static_cast<size_t>(start)))
+        if (start < 0 || linesCollection.contains(start))
             numberOfLines--;
     }
 
     return start + 1;
 }
 
-static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
 {
     ASSERT(!position.namedGridLine().isNull());
 
-    const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
-    auto iterator = gridLinesNames.find(position.namedGridLine());
-    const Vector<unsigned>* gridLines = iterator == gridLinesNames.end() ? nullptr : &iterator->value;
-    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
+    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
+    NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
+
     if (position.isPositive())
-        return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), gridLines, lastLine);
-    return lookBackForNamedGridLine(lastLine, std::abs(position.integerPosition()), gridLines, lastLine);
+        return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), lastLine, linesCollection);
+    return lookBackForNamedGridLine(lastLine, std::abs(position.integerPosition()), lastLine, linesCollection);
 }
 
-static GridSpan definiteGridSpanWithNamedLineSpanAgainstOpposite(int oppositeLine, const GridPosition& position, GridPositionSide side, const Vector<unsigned>* gridLines, unsigned lastLine)
+static GridSpan definiteGridSpanWithNamedLineSpanAgainstOpposite(int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned lastLine, NamedLineCollection& linesCollection)
 {
     int start, end;
-
     if (side == RowStartSide || side == ColumnStartSide) {
-        start = lookBackForNamedGridLine(oppositeLine - 1, position.spanPosition(), gridLines, lastLine);
+        start = lookBackForNamedGridLine(oppositeLine - 1, position.spanPosition(), lastLine, linesCollection);
         end = oppositeLine;
     } else {
         start = oppositeLine;
-        end = lookAheadForNamedGridLine(oppositeLine + 1, position.spanPosition(), gridLines, lastLine);
+        end = lookAheadForNamedGridLine(oppositeLine + 1, position.spanPosition(), lastLine, linesCollection);
     }
 
     return GridSpan::untranslatedDefiniteGridSpan(start, end);
 }
 
-static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side)
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
 {
     ASSERT(position.isSpan());
     ASSERT(!position.namedGridLine().isNull());
     // Negative positions are not allowed per the specification and should have been handled during parsing.
     ASSERT(position.spanPosition() > 0);
 
-    const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
-    auto iterator = gridLinesNames.find(position.namedGridLine());
-    const Vector<unsigned>* gridLines = iterator == gridLinesNames.end() ? nullptr : &iterator->value;
-    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
-
-    return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, gridLines, lastLine);
+    unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
+    NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
+    return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, lastLine, linesCollection);
 }
 
-static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side)
+static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
 {
     if (position.isAuto()) {
         if (isStartSide(side))
@@ -212,7 +288,7 @@
 
     if (!position.namedGridLine().isNull()) {
         // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
-        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side);
+        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side, autoRepeatTracksCount);
     }
 
     // 'span 1' is contained inside a single grid track regardless of the direction.
@@ -242,21 +318,21 @@
     return position.spanPosition();
 }
 
-static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
 {
     switch (position.type()) {
     case ExplicitPosition: {
         ASSERT(position.integerPosition());
 
         if (!position.namedGridLine().isNull())
-            return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side);
+            return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side, autoRepeatTracksCount);
 
         // Handle <integer> explicit position.
         if (position.isPositive())
             return position.integerPosition() - 1;
 
         unsigned resolvedPosition = std::abs(position.integerPosition()) - 1;
-        const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side);
+        const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
 
         return endOfTrack - resolvedPosition;
     }
@@ -268,20 +344,19 @@
         String namedGridLine = position.namedGridLine();
         ASSERT(!position.namedGridLine().isNull());
 
-        const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side);
-        auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
-        if (implicitLine != gridLineNames.end())
-            return implicitLine->value[0];
+        unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
+        NamedLineCollection implicitLines(gridContainerStyle, implicitNamedGridLineForSide(namedGridLine, side), directionFromSide(side), lastLine, autoRepeatTracksCount);
+        if (implicitLines.hasNamedLines())
+            return implicitLines.firstPosition();
 
         // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
         // item's placement.
-        auto explicitLine = gridLineNames.find(namedGridLine);
-        if (explicitLine != gridLineNames.end())
-            return explicitLine->value[0];
+        NamedLineCollection explicitLines(gridContainerStyle, namedGridLine, directionFromSide(side), lastLine, autoRepeatTracksCount);
+        if (explicitLines.hasNamedLines())
+            return explicitLines.firstPosition();
 
-        ASSERT(GridPositionsResolver::isNonExistentNamedLineOrArea(namedGridLine, gridContainerStyle, side));
+        ASSERT(!NamedLineCollection::isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side));
         // If none of the above works specs mandate to assume that all the lines in the implicit grid have this name.
-        unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
         return lastLine + 1;
     }
     case AutoPosition:
@@ -294,7 +369,7 @@
     return 0;
 }
 
-GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction)
+GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, unsigned autoRepeatTracksCount)
 {
     GridPosition initialPosition, finalPosition;
     adjustGridPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition);
@@ -308,18 +383,18 @@
 
     if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
         // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
-        auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide);
-        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide);
+        auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide, autoRepeatTracksCount);
     }
 
     if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
         // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
-        auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide);
-        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide);
+        auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide, autoRepeatTracksCount);
     }
 
-    int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide);
-    int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide);
+    int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
+    int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
 
     if (startLine > endLine)
         std::swap(startLine, endLine);

Modified: trunk/Source/WebCore/rendering/style/GridPositionsResolver.h (200367 => 200368)


--- trunk/Source/WebCore/rendering/style/GridPositionsResolver.h	2016-05-03 09:18:40 UTC (rev 200367)
+++ trunk/Source/WebCore/rendering/style/GridPositionsResolver.h	2016-05-03 11:30:29 UTC (rev 200368)
@@ -46,14 +46,36 @@
     ForRows
 };
 
+class NamedLineCollection {
+    WTF_MAKE_NONCOPYABLE(NamedLineCollection);
+public:
+    NamedLineCollection(const RenderStyle&, const String& namedLine, GridTrackSizingDirection, unsigned lastLine, unsigned autoRepeatTracksCount);
+
+    static bool isValidNamedLineOrArea(const String& namedLine, const RenderStyle&, GridPositionSide);
+
+    bool hasNamedLines() const;
+    unsigned firstPosition() const;
+
+    bool contains(unsigned line) const;
+
+private:
+    size_t find(unsigned line) const;
+
+    const Vector<unsigned>* m_namedLinesIndexes { nullptr };
+    const Vector<unsigned>* m_autoRepeatNamedLinesIndexes { nullptr };
+
+    unsigned m_insertionPoint;
+    unsigned m_lastLine;
+    unsigned m_repetitions;
+};
+
 // Class with all the code related to grid items positions resolution.
 class GridPositionsResolver {
 public:
     static unsigned spanSizeForAutoPlacedItem(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
-    static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
-    static unsigned explicitGridColumnCount(const RenderStyle&);
-    static unsigned explicitGridRowCount(const RenderStyle&);
-    static bool isNonExistentNamedLineOrArea(const String& lineName, const RenderStyle&, GridPositionSide);
+    static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, unsigned autoRepeatTracksCount);
+    static unsigned explicitGridColumnCount(const RenderStyle&, unsigned autoRepeatColumnsCount);
+    static unsigned explicitGridRowCount(const RenderStyle&, unsigned autoRepeatRowsCount);
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to