Bug 1009272 - [css-grid] Add some sanity checks for the grid container child frame lists. r=dholbert
authorMats Palmgren <matspal@gmail.com>
Mon, 19 May 2014 23:57:00 +0000
changeset 184001 57f1981b6a49710bf7a8afcd57d2410c165e1ab3
parent 184000 37e1dd2155b68297531da4d122da2b9f5b20d146
child 184002 9c12250ddf175c151661626a3f3a3d7ed4eac9e4
push id26810
push usercbook@mozilla.com
push dateWed, 21 May 2014 11:46:36 +0000
treeherdermozilla-central@50fb8c4db2fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1009272
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1009272 - [css-grid] Add some sanity checks for the grid container child frame lists. r=dholbert
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1547,17 +1547,17 @@ nsFlexContainerFrame::BuildDisplayList(n
 }
 
 #ifdef DEBUG
 // helper for the debugging method below
 bool
 FrameWantsToBeInAnonymousFlexItem(nsIFrame* aFrame)
 {
   // Note: This needs to match the logic in
-  // nsCSSFrameConstructor::FrameConstructionItem::NeedsAnonFlexItem()
+  // nsCSSFrameConstructor::FrameConstructionItem::NeedsAnonFlexOrGridItem()
   return (aFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
           nsGkAtoms::placeholderFrame == aFrame->GetType());
 }
 
 // Debugging method, to let us assert that our anonymous flex items are
 // set up correctly -- in particular, we assert:
 //  (1) we don't have any inline non-replaced children
 //  (2) we don't have any consecutive anonymous flex items
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -3,16 +3,17 @@
 /* This Source Code is subject to the terms of the Mozilla Public License
  * version 2.0 (the "License"). You can obtain a copy of the License at
  * http://mozilla.org/MPL/2.0/. */
 
 /* rendering object for CSS "display: grid | inline-grid" */
 
 #include "nsGridContainerFrame.h"
 
+#include "nsCSSAnonBoxes.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 
 //----------------------------------------------------------------------
 
 // Frame class boilerplate
 // =======================
 
@@ -43,16 +44,20 @@ nsGridContainerFrame::Reflow(nsPresConte
 {
   DO_GLOBAL_REFLOW_COUNT("nsGridContainerFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
   if (IsFrameTreeTooDeep(aReflowState, aDesiredSize, aStatus)) {
     return;
   }
 
+#ifdef DEBUG
+  SanityCheckAnonymousGridItems();
+#endif // DEBUG
+
   nsMargin bp = aReflowState.ComputedPhysicalBorderPadding();
   ApplySkipSides(bp);
   nscoord contentHeight = GetEffectiveComputedHeight(aReflowState);
   if (contentHeight == NS_AUTOHEIGHT) {
     contentHeight = 0;
   }
   aDesiredSize.Width() = aReflowState.ComputedWidth() + bp.LeftRight();
   aDesiredSize.Height() = contentHeight + bp.TopBottom();
@@ -69,8 +74,69 @@ nsGridContainerFrame::GetType() const
 
 #ifdef DEBUG_FRAME_DUMP
 nsresult
 nsGridContainerFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("GridContainer"), aResult);
 }
 #endif
+
+#ifdef DEBUG
+static bool
+FrameWantsToBeInAnonymousGridItem(nsIFrame* aFrame)
+{
+  // Note: This needs to match the logic in
+  // nsCSSFrameConstructor::FrameConstructionItem::NeedsAnonFlexOrGridItem()
+  return (aFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
+          nsGkAtoms::placeholderFrame == aFrame->GetType());
+}
+
+// Debugging method, to let us assert that our anonymous grid items are
+// set up correctly -- in particular, we assert:
+//  (1) we don't have any inline non-replaced children
+//  (2) we don't have any consecutive anonymous grid items
+//  (3) we don't have any empty anonymous grid items
+//  (4) all children are on the expected child lists
+void
+nsGridContainerFrame::SanityCheckAnonymousGridItems() const
+{
+  // XXX handle kOverflowContainersList / kExcessOverflowContainersList
+  // when we implement fragmentation?
+  ChildListIDs noCheckLists = kAbsoluteList | kFixedList;
+  ChildListIDs checkLists = kPrincipalList | kOverflowList;
+  for (nsIFrame::ChildListIterator childLists(this);
+       !childLists.IsDone(); childLists.Next()) {
+    if (!checkLists.Contains(childLists.CurrentID())) {
+      MOZ_ASSERT(noCheckLists.Contains(childLists.CurrentID()),
+                 "unexpected non-empty child list");
+      continue;
+    }
+
+    bool prevChildWasAnonGridItem = false;
+    nsFrameList children = childLists.CurrentList();
+    for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
+      nsIFrame* child = e.get();
+      MOZ_ASSERT(!FrameWantsToBeInAnonymousGridItem(child),
+                 "frame wants to be inside an anonymous grid item, "
+                 "but it isn't");
+      if (child->StyleContext()->GetPseudo() ==
+            nsCSSAnonBoxes::anonymousGridItem) {
+/*
+  XXX haven't decided yet whether to reorder children or not.
+  XXX If we do, we want this assertion instead of the one below.
+        MOZ_ASSERT(!prevChildWasAnonGridItem ||
+                   HasAnyStateBits(NS_STATE_GRID_CHILDREN_REORDERED),
+                   "two anon grid items in a row (shouldn't happen, unless our "
+                   "children have been reordered with the 'order' property)");
+*/
+        MOZ_ASSERT(!prevChildWasAnonGridItem, "two anon grid items in a row");
+        nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild();
+        MOZ_ASSERT(firstWrappedChild,
+                   "anonymous grid item is empty (shouldn't happen)");
+        prevChildWasAnonGridItem = true;
+      } else {
+        prevChildWasAnonGridItem = false;
+      }
+    }
+  }
+}
+#endif // DEBUG
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -35,11 +35,15 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
 protected:
   friend nsIFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
                                             nsStyleContext* aContext);
   nsGridContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
+
+#ifdef DEBUG
+  void SanityCheckAnonymousGridItems() const;
+#endif // DEBUG
 };
 
 #endif /* nsGridContainerFrame_h___ */