Bug 1423378 Part 1: Specially treat the explicit line names following a repeat auto-fit or auto-fill declaration to ensure they are always applied to the following line. draft
authorBrad Werth <bwerth@mozilla.com>
Tue, 05 Dec 2017 14:51:06 -0800
changeset 716566 1ceed8e9b4745c834a5265116e4c118c12633239
parent 716325 81362f7306fe413b19fdba27cd0e9a5525d902e1
child 716567 98d5583bfd931047d2f4c3399bdc34ac78ef3bc1
push id94461
push userbwerth@mozilla.com
push dateFri, 05 Jan 2018 23:21:23 +0000
bugs1423378
milestone59.0a1
Bug 1423378 Part 1: Specially treat the explicit line names following a repeat auto-fit or auto-fill declaration to ensure they are always applied to the following line. MozReview-Commit-ID: iFM5J6wRL6
dom/grid/GridLines.cpp
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/dom/grid/GridLines.cpp
+++ b/dom/grid/GridLines.cpp
@@ -132,25 +132,21 @@ GridLines::SetLineInfo(const ComputedGri
 
       // Get the line names for the current line. aLineInfo->mNames
       // may contain duplicate names. This is intentional, since grid
       // layout works fine with duplicate names, and we don't want to
       // detect and remove duplicates in layout since it is an O(n^2)
       // problem. We do the work here since this is only run when
       // requested by devtools, and slowness here will not affect
       // normal browsing.
-      nsTArray<nsString> possiblyDuplicateLineNames(
+      const nsTArray<nsString>& possiblyDuplicateLineNames(
         aLineInfo->mNames.SafeElementAt(i, nsTArray<nsString>()));
 
-      // Add the possiblyDuplicateLineNames one at a time to filter
-      // out the duplicates.
       nsTArray<nsString> lineNames;
-      for (const auto& name : possiblyDuplicateLineNames) {
-        AddLineNameIfNotPresent(lineNames, name);
-      }
+      AddLineNamesIfNotPresent(lineNames, possiblyDuplicateLineNames);
 
       // Add in names from grid areas where this line is used as a boundary.
       for (auto area : aAreas) {
         bool haveNameToAdd = false;
         nsAutoString nameToAdd;
         area->GetName(nameToAdd);
         if (aIsRow) {
           if (area->RowStart() == line1Index) {
@@ -182,16 +178,26 @@ GridLines::SetLineInfo(const ComputedGri
                                                aLineInfo,
                                                lastTrackEdge,
                                                repeatIndex,
                                                numRepeatTracks,
                                                leadingTrackCount,
                                                lineNames);
       }
 
+      // If this line is the one that ends a repeat, then add
+      // in the mNamesFollowingRepeat names from aLineInfo.
+      if (numRepeatTracks > 0 &&
+          i == (aTrackInfo->mRepeatFirstTrack +
+                aTrackInfo->mNumLeadingImplicitTracks +
+                numRepeatTracks - numAddedLines)) {
+        AddLineNamesIfNotPresent(lineNames,
+                                 aLineInfo->mNamesFollowingRepeat);
+      }
+
       RefPtr<GridLine> line = new GridLine(this);
       mLines.AppendElement(line);
       MOZ_ASSERT(line1Index > 0, "line1Index must be positive.");
       bool isBeforeFirstExplicit =
         (line1Index <= aTrackInfo->mNumLeadingImplicitTracks);
       bool isAfterLastExplicit = line1Index > (leadingTrackCount + 1);
       // Calculate an actionable line number for this line, that could be used
       // in a css grid property to align a grid item or area at that line.
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -1628,30 +1628,24 @@ struct nsGridContainerFrame::Tracks
       const uint32_t repeatAutoStart = aGridTemplate.mRepeatAutoIndex;
       const uint32_t repeatAutoEnd = (repeatAutoStart + repeatTrackCount);
       const int32_t repeatEndDelta = int32_t(repeatTrackCount - 1);
 
       if (aIndex <= repeatAutoStart) {
         if (aIndex < lineNameLists.Length()) {
           lineNames.AppendElements(lineNameLists[aIndex]);
         }
-        if (aIndex == repeatAutoEnd) {
-          uint32_t i = aIndex + 1;
-          if (i < lineNameLists.Length()) {
-            lineNames.AppendElements(lineNameLists[i]);
-          }
-        }
       }
       if (aIndex <= repeatAutoEnd && aIndex > repeatAutoStart) {
         lineNames.AppendElements(aGridTemplate.mRepeatAutoLineNameListAfter);
       }
       if (aIndex < repeatAutoEnd && aIndex >= repeatAutoStart) {
         lineNames.AppendElements(aGridTemplate.mRepeatAutoLineNameListBefore);
       }
-      if (aIndex >= repeatAutoEnd && aIndex > repeatAutoStart) {
+      if (aIndex > repeatAutoEnd && aIndex > repeatAutoStart) {
         uint32_t i = aIndex - repeatEndDelta;
         if (i < lineNameLists.Length()) {
           lineNames.AppendElements(lineNameLists[i]);
         }
       }
     }
 
     return lineNames;
@@ -6236,20 +6230,32 @@ nsGridContainerFrame::Reflow(nsPresConte
       nsTArray<nsString> explicitNames =
         gridReflowInput.mCols.GetExplicitLineNamesAtIndex(
           gridColTemplate,
           gridReflowInput.mColFunctions,
           col - gridReflowInput.mColFunctions.mExplicitGridOffset);
 
       columnLineNames.AppendElement(explicitNames);
     }
+    // Get the explicit names that follow a repeat auto declaration.
+    nsTArray<nsString> colNamesFollowingRepeat;
+    if (gridColTemplate.HasRepeatAuto()) {
+      // The line name list after the repeatAutoIndex holds the line names
+      // for the first explicit line after the repeat auto declaration.
+      uint32_t repeatAutoEnd = gridColTemplate.mRepeatAutoIndex + 1;
+      MOZ_ASSERT(repeatAutoEnd < gridColTemplate.mLineNameLists.Length());
+      colNamesFollowingRepeat.AppendElements(
+        gridColTemplate.mLineNameLists[repeatAutoEnd]);
+    }
+
     ComputedGridLineInfo* columnLineInfo = new ComputedGridLineInfo(
       Move(columnLineNames),
       gridColTemplate.mRepeatAutoLineNameListBefore,
-      gridColTemplate.mRepeatAutoLineNameListAfter);
+      gridColTemplate.mRepeatAutoLineNameListAfter,
+      Move(colNamesFollowingRepeat));
     SetProperty(GridColumnLineInfo(), columnLineInfo);
 
     // Generate row lines next.
     capacity = gridReflowInput.mRows.mSizes.Length();
     const nsStyleGridTemplate& gridRowTemplate =
       gridReflowInput.mGridStyle->GridTemplateRows();
     nsTArray<nsTArray<nsString>> rowLineNames(capacity);
     for (row = 0; row <= gridReflowInput.mRows.mSizes.Length(); row++) {
@@ -6257,20 +6263,32 @@ nsGridContainerFrame::Reflow(nsPresConte
       nsTArray<nsString> explicitNames =
         gridReflowInput.mRows.GetExplicitLineNamesAtIndex(
           gridRowTemplate,
           gridReflowInput.mRowFunctions,
           row - gridReflowInput.mRowFunctions.mExplicitGridOffset);
 
       rowLineNames.AppendElement(explicitNames);
     }
+    // Get the explicit names that follow a repeat auto declaration.
+    nsTArray<nsString> rowNamesFollowingRepeat;
+    if (gridRowTemplate.HasRepeatAuto()) {
+      // The line name list after the repeatAutoIndex holds the line names
+      // for the first explicit line after the repeat auto declaration.
+      uint32_t repeatAutoEnd = gridRowTemplate.mRepeatAutoIndex + 1;
+      MOZ_ASSERT(repeatAutoEnd < gridRowTemplate.mLineNameLists.Length());
+      rowNamesFollowingRepeat.AppendElements(
+        gridRowTemplate.mLineNameLists[repeatAutoEnd]);
+    }
+
     ComputedGridLineInfo* rowLineInfo = new ComputedGridLineInfo(
       Move(rowLineNames),
       gridRowTemplate.mRepeatAutoLineNameListBefore,
-      gridRowTemplate.mRepeatAutoLineNameListAfter);
+      gridRowTemplate.mRepeatAutoLineNameListAfter,
+      Move(rowNamesFollowingRepeat));
     SetProperty(GridRowLineInfo(), rowLineInfo);
 
     // Generate area info for explicit areas. Implicit areas are handled
     // elsewhere.
     if (gridReflowInput.mGridStyle->mGridTemplateAreas) {
       nsTArray<css::GridNamedArea>* areas = new nsTArray<css::GridNamedArea>(
           gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas);
       SetProperty(ExplicitNamedAreasProperty(), areas);
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -65,24 +65,27 @@ struct ComputedGridTrackInfo
   nsTArray<bool> mRemovedRepeatTracks;
   uint32_t mRepeatFirstTrack;
 };
 
 struct ComputedGridLineInfo
 {
   explicit ComputedGridLineInfo(nsTArray<nsTArray<nsString>>&& aNames,
                                 const nsTArray<nsString>& aNamesBefore,
-                                const nsTArray<nsString>& aNamesAfter)
+                                const nsTArray<nsString>& aNamesAfter,
+                                nsTArray<nsString>&& aNamesFollowingRepeat)
     : mNames(aNames)
     , mNamesBefore(aNamesBefore)
     , mNamesAfter(aNamesAfter)
+    , mNamesFollowingRepeat(aNamesFollowingRepeat)
   {}
   nsTArray<nsTArray<nsString>> mNames;
   nsTArray<nsString> mNamesBefore;
   nsTArray<nsString> mNamesAfter;
+  nsTArray<nsString> mNamesFollowingRepeat;
 };
 } // namespace mozilla
 
 class nsGridContainerFrame final : public nsContainerFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsGridContainerFrame)
   NS_DECL_QUERYFRAME