| Index: third_party/WebKit/Source/core/layout/LayoutGrid.cpp
 | 
| diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
 | 
| index cfde1c770390d00cb5a418ebb7f1d54fd22443fa..c007251ba0e73d41af47e48c685757e46e17ea89 100644
 | 
| --- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
 | 
| +++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
 | 
| @@ -301,7 +301,8 @@ void LayoutGrid::styleDidChange(StyleDifference diff, const ComputedStyle* oldSt
 | 
|  
 | 
|      if (explicitGridDidResize(*oldStyle)
 | 
|          || namedGridLinesDefinitionDidChange(*oldStyle)
 | 
| -        || oldStyle->getGridAutoFlow() != styleRef().getGridAutoFlow())
 | 
| +        || oldStyle->getGridAutoFlow() != styleRef().getGridAutoFlow()
 | 
| +        || (diff.needsLayout() && (styleRef().gridAutoRepeatColumns().size() || styleRef().gridAutoRepeatRows().size())))
 | 
|          dirtyGrid();
 | 
|  }
 | 
|  
 | 
| @@ -310,7 +311,9 @@ bool LayoutGrid::explicitGridDidResize(const ComputedStyle& oldStyle) const
 | 
|      return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColumns().size()
 | 
|          || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().size()
 | 
|          || oldStyle.namedGridAreaColumnCount() != styleRef().namedGridAreaColumnCount()
 | 
| -        || oldStyle.namedGridAreaRowCount() != styleRef().namedGridAreaRowCount();
 | 
| +        || oldStyle.namedGridAreaRowCount() != styleRef().namedGridAreaRowCount()
 | 
| +        || oldStyle.gridAutoRepeatColumns().size() != styleRef().gridAutoRepeatColumns().size()
 | 
| +        || oldStyle.gridAutoRepeatRows().size() != styleRef().gridAutoRepeatRows().size();
 | 
|  }
 | 
|  
 | 
|  bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle) const
 | 
| @@ -694,13 +697,40 @@ static bool shouldClearOverrideContainingBlockContentSizeForChild(const LayoutBo
 | 
|      return child.hasRelativeLogicalHeight() || child.styleRef().logicalHeight().isIntrinsicOrAuto();
 | 
|  }
 | 
|  
 | 
| -GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size_t i) const
 | 
| +const GridTrackSize& LayoutGrid::rawGridTrackSize(GridTrackSizingDirection direction, size_t translatedIndex) const
 | 
|  {
 | 
| -    bool isForColumns = direction == ForColumns;
 | 
| -    const Vector<GridTrackSize>& trackStyles = isForColumns ? style()->gridTemplateColumns() : style()->gridTemplateRows();
 | 
| -    const GridTrackSize& autoTrackSize = isForColumns ? style()->gridAutoColumns() : style()->gridAutoRows();
 | 
| -    int translatedIndex = i + (isForColumns ? m_smallestColumnStart : m_smallestRowStart);
 | 
| -    const GridTrackSize& trackSize = (translatedIndex < 0 || translatedIndex >= static_cast<int>(trackStyles.size())) ? autoTrackSize : trackStyles[translatedIndex];
 | 
| +    bool isRowAxis = direction == ForColumns;
 | 
| +    const Vector<GridTrackSize>& trackStyles = isRowAxis ? styleRef().gridTemplateColumns() : styleRef().gridTemplateRows();
 | 
| +    const Vector<GridTrackSize>& autoRepeatTrackStyles = isRowAxis ? styleRef().gridAutoRepeatColumns() : styleRef().gridAutoRepeatRows();
 | 
| +    const GridTrackSize& autoTrackSize = isRowAxis ? styleRef().gridAutoColumns() : styleRef().gridAutoRows();
 | 
| +    size_t insertionPoint = isRowAxis ? styleRef().gridAutoRepeatColumnsInsertionPoint() : styleRef().gridAutoRepeatRowsInsertionPoint();
 | 
| +    size_t repetitions = autoRepeatCountForDirection(direction);
 | 
| +
 | 
| +    // We should not use GridPositionsResolver::explicitGridXXXCount() for this because the
 | 
| +    // explicit grid might be larger than the number of tracks in grid-template-rows|columns (if
 | 
| +    // grid-template-areas is specified for example).
 | 
| +    size_t explicitTracksCount = trackStyles.size() + repetitions;
 | 
| +
 | 
| +    int untranslatedIndexAsInt = translatedIndex + (isRowAxis ? m_smallestColumnStart : m_smallestRowStart);
 | 
| +    if (untranslatedIndexAsInt < 0)
 | 
| +        return autoTrackSize;
 | 
| +
 | 
| +    size_t untranslatedIndex = static_cast<size_t>(untranslatedIndexAsInt);
 | 
| +    if (untranslatedIndex >= explicitTracksCount)
 | 
| +        return autoTrackSize;
 | 
| +
 | 
| +    if (LIKELY(!repetitions) || untranslatedIndex < insertionPoint)
 | 
| +        return trackStyles[untranslatedIndex];
 | 
| +
 | 
| +    if (untranslatedIndex < (insertionPoint + repetitions))
 | 
| +        return autoRepeatTrackStyles[0];
 | 
| +
 | 
| +    return trackStyles[untranslatedIndex - repetitions];
 | 
| +}
 | 
| +
 | 
| +GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size_t translatedIndex) const
 | 
| +{
 | 
| +    const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex);
 | 
|  
 | 
|      GridLength minTrackBreadth = trackSize.minTrackBreadth();
 | 
|      GridLength maxTrackBreadth = trackSize.maxTrackBreadth();
 | 
| @@ -1182,8 +1212,77 @@ void LayoutGrid::insertItemIntoGrid(LayoutBox& child, const GridArea& area)
 | 
|  
 | 
|  size_t LayoutGrid::computeAutoRepeatTracksCount(GridTrackSizingDirection direction) const
 | 
|  {
 | 
| -    // TODO(svillar): implement the algorithm to compute the number of auto repeat tracks.
 | 
| -    return 0;
 | 
| +    bool isRowAxis = direction == ForColumns;
 | 
| +    const auto& autoRepeatTracks = isRowAxis ? styleRef().gridAutoRepeatColumns() : styleRef().gridAutoRepeatRows();
 | 
| +
 | 
| +    if (!autoRepeatTracks.size())
 | 
| +        return 0;
 | 
| +
 | 
| +    DCHECK_EQ(autoRepeatTracks.size(), static_cast<size_t>(1));
 | 
| +    auto autoTrackSize = autoRepeatTracks.at(0);
 | 
| +    DCHECK(autoTrackSize.minTrackBreadth().isLength());
 | 
| +    DCHECK(!autoTrackSize.minTrackBreadth().isContentSized());
 | 
| +
 | 
| +    LayoutUnit availableSize = isRowAxis ? availableLogicalWidth() : computeContentLogicalHeight(MainOrPreferredSize, styleRef().logicalHeight(), LayoutUnit(-1));
 | 
| +    if (availableSize == -1) {
 | 
| +        const Length& maxLength = isRowAxis ? styleRef().logicalMaxWidth() : styleRef().logicalMaxHeight();
 | 
| +        if (!maxLength.isMaxSizeNone()) {
 | 
| +            availableSize = isRowAxis
 | 
| +                ? computeLogicalWidthUsing(MaxSize, maxLength, containingBlockLogicalWidthForContent(), containingBlock())
 | 
| +                : computeContentLogicalHeight(MaxSize, maxLength, LayoutUnit(-1));
 | 
| +        }
 | 
| +    } else {
 | 
| +        availableSize = isRowAxis
 | 
| +            ? constrainLogicalWidthByMinMax(availableSize, availableLogicalWidth(), containingBlock())
 | 
| +            : constrainLogicalHeightByMinMax(availableSize, LayoutUnit(-1));
 | 
| +    }
 | 
| +
 | 
| +    bool needsToFulfillMinimumSize = false;
 | 
| +    bool indefiniteMainAndMaxSizes = availableSize == LayoutUnit(-1);
 | 
| +    if (indefiniteMainAndMaxSizes) {
 | 
| +        const Length& minSize = isRowAxis ? styleRef().logicalMinWidth() : styleRef().logicalMinHeight();
 | 
| +        if (!minSize.isSpecified())
 | 
| +            return 1;
 | 
| +
 | 
| +        LayoutUnit containingBlockAvailableSize = isRowAxis ? containingBlockLogicalWidthForContent() : containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
 | 
| +        availableSize = valueForLength(minSize, containingBlockAvailableSize);
 | 
| +        needsToFulfillMinimumSize = true;
 | 
| +    }
 | 
| +
 | 
| +    bool hasDefiniteMaxTrackSizingFunction = autoTrackSize.maxTrackBreadth().isLength() && !autoTrackSize.maxTrackBreadth().isContentSized();
 | 
| +    const Length trackLength = hasDefiniteMaxTrackSizingFunction ? autoTrackSize.maxTrackBreadth().length() : autoTrackSize.minTrackBreadth().length();
 | 
| +    // For the purpose of finding the number of auto-repeated tracks, the UA must floor the track size to a UA-specified
 | 
| +    // value to avoid division by zero. It is suggested that this floor be 1px.
 | 
| +    LayoutUnit autoRepeatTrackSize = std::max<LayoutUnit>(LayoutUnit(1), valueForLength(trackLength, availableSize));
 | 
| +
 | 
| +    // There will be always at least 1 auto-repeat track, so take it already into account when computing the total track size.
 | 
| +    LayoutUnit tracksSize = autoRepeatTrackSize;
 | 
| +    const Vector<GridTrackSize>& trackSizes = isRowAxis ? styleRef().gridTemplateColumns() : styleRef().gridTemplateRows();
 | 
| +
 | 
| +    for (const auto& track : trackSizes) {
 | 
| +        bool hasDefiniteMaxTrackBreadth = track.maxTrackBreadth().isLength() && !track.maxTrackBreadth().isContentSized();
 | 
| +        DCHECK(hasDefiniteMaxTrackBreadth || (track.minTrackBreadth().isLength() && !track.minTrackBreadth().isContentSized()));
 | 
| +        tracksSize += valueForLength(hasDefiniteMaxTrackBreadth ? track.maxTrackBreadth().length() : track.minTrackBreadth().length(), availableSize);
 | 
| +    }
 | 
| +
 | 
| +    // Add gutters as if there where only 1 auto repeat track. Gaps between auto repeat tracks will be added later when
 | 
| +    // computing the repetitions.
 | 
| +    LayoutUnit gapSize = guttersSize(direction, 2);
 | 
| +    tracksSize += gapSize * trackSizes.size();
 | 
| +
 | 
| +    LayoutUnit freeSpace = availableSize - tracksSize;
 | 
| +    if (freeSpace <= 0)
 | 
| +        return 1;
 | 
| +
 | 
| +    size_t repetitions = 1 + (freeSpace / (autoRepeatTrackSize + gapSize)).toInt();
 | 
| +
 | 
| +    // Provided the grid container does not have a definite size or max-size in the relevant axis,
 | 
| +    // if the min size is definite then the number of repetitions is the largest possible positive
 | 
| +    // integer that fulfills that minimum requirement.
 | 
| +    if (needsToFulfillMinimumSize)
 | 
| +        ++repetitions;
 | 
| +
 | 
| +    return repetitions;
 | 
|  }
 | 
|  
 | 
|  void LayoutGrid::placeItemsOnGrid()
 | 
| 
 |