Bug 1144096 part 20 - [css-grid] Sanity check our child lists before starting a Reflow (DEBUG only). r=dholbert
authorMats Palmgren <mats@mozilla.com>
Fri, 11 Mar 2016 17:39:27 +0100
changeset 339573 557bb3ae736f484ca7671ba9ec84b09e24ac7d70
parent 339572 2a7ef2dd4427641166c3a49d3311f5d092337961
child 339574 e8b769cce0f101f39284954ec6a826c0cd6343cf
push id12762
push userbmo:rail@mozilla.com
push dateFri, 11 Mar 2016 19:47:45 +0000
reviewersdholbert
bugs1144096
milestone48.0a1
Bug 1144096 part 20 - [css-grid] Sanity check our child lists before starting a Reflow (DEBUG only). r=dholbert
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -4949,17 +4949,17 @@ nsGridContainerFrame::Reflow(nsPresConte
     }
 
     MOZ_ASSERT(foundOwnPushedChild || !items.IsEmpty(),
                "NS_STATE_GRID_DID_PUSH_ITEMS lied");
     ::MergeSortedFrameLists(mFrames, items, GetContent());
   }
 
 #ifdef DEBUG
-  SanityCheckAnonymousGridItems();
+  SanityCheckGridItemsBeforeReflow();
 #endif // DEBUG
 
   const nsStylePosition* stylePos = aReflowState.mStylePosition;
   if (!prevInFlow) {
     InitImplicitNamedAreas(stylePos);
   }
   GridReflowState gridReflowState(this, aReflowState);
   if (gridReflowState.mIter.ItemsAreAlreadyInOrder()) {
@@ -5291,18 +5291,56 @@ nsGridContainerFrame::SetInitialChildLis
       }
     }
   }
 
   return nsContainerFrame::SetInitialChildList(aListID, aChildList);
 }
 
 void
-nsGridContainerFrame::SanityCheckAnonymousGridItems() const
+nsGridContainerFrame::SanityCheckGridItemsBeforeReflow() const
 {
+  ChildListIDs absLists = kAbsoluteList | kFixedList |
+    kOverflowContainersList | kExcessOverflowContainersList;
+  ChildListIDs itemLists = kPrincipalList | kOverflowList;
+  for (const nsIFrame* f = this; f; f = f->GetNextInFlow()) {
+    MOZ_ASSERT(!f->HasAnyStateBits(NS_STATE_GRID_DID_PUSH_ITEMS),
+               "At start of reflow, we should've pulled items back from all "
+               "NIFs and cleared NS_STATE_GRID_DID_PUSH_ITEMS in the process");
+    for (nsIFrame::ChildListIterator childLists(f);
+         !childLists.IsDone(); childLists.Next()) {
+      if (!itemLists.Contains(childLists.CurrentID())) {
+        MOZ_ASSERT(absLists.Contains(childLists.CurrentID()),
+                   "unexpected non-empty child list");
+        continue;
+      }
+      for (auto child : childLists.CurrentList()) {
+        MOZ_ASSERT(f == this || child->GetPrevInFlow(),
+                   "all pushed items must be pulled up before reflow");
+      }
+    }
+  }
+  // If we have a prev-in-flow, each of its children's next-in-flow
+  // should be one of our children or be null.
+  const auto pif = static_cast<nsGridContainerFrame*>(GetPrevInFlow());
+  if (pif) {
+    const nsFrameList* oc =
+      GetPropTableFrames(OverflowContainersProperty());
+    const nsFrameList* eoc =
+      GetPropTableFrames(ExcessOverflowContainersProperty());
+    const nsFrameList* pifEOC =
+      pif->GetPropTableFrames(ExcessOverflowContainersProperty());
+    for (const nsIFrame* child : pif->GetChildList(kPrincipalList)) {
+      const nsIFrame* childNIF = child->GetNextInFlow();
+      MOZ_ASSERT(!childNIF || mFrames.ContainsFrame(childNIF) ||
+                 (pifEOC && pifEOC->ContainsFrame(childNIF)) ||
+                 (oc && oc->ContainsFrame(childNIF)) ||
+                 (eoc && eoc->ContainsFrame(childNIF)));
+    }
+  }
 }
 
 void
 nsGridContainerFrame::TrackSize::Dump() const
 {
   printf("mPosition=%d mBase=%d mLimit=%d", mPosition, mBase, mLimit);
 
   printf(" min:");
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -157,17 +157,17 @@ protected:
                          IntrinsicISizeType  aConstraint);
 
   // Helper to move child frames into the kOverflowList.
   void MergeSortedOverflow(nsFrameList& aList);
   // Helper to move child frames into the kExcessOverflowContainersList:.
   void MergeSortedExcessOverflowContainers(nsFrameList& aList);
 
 #ifdef DEBUG
-  void SanityCheckAnonymousGridItems() const;
+  void SanityCheckGridItemsBeforeReflow() const;
 #endif // DEBUG
 
 private:
   // Helpers for ReflowChildren
   struct Fragmentainer {
     /**
      * The distance from the first grid container fragment's block-axis content
      * edge to the fragmentainer end.