Bumping manifests a=b2g-bump
[gecko.git] / layout / generic / nsGridContainerFrame.cpp
blobbf4fc4d36772dfa8e8f3ab0d46a2a67aaaadc101
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code is subject to the terms of the Mozilla Public License
4 * version 2.0 (the "License"). You can obtain a copy of the License at
5 * http://mozilla.org/MPL/2.0/. */
7 /* rendering object for CSS "display: grid | inline-grid" */
9 #include "nsGridContainerFrame.h"
11 #include "nsCSSAnonBoxes.h"
12 #include "nsPresContext.h"
13 #include "nsStyleContext.h"
15 using namespace mozilla;
17 //----------------------------------------------------------------------
19 // Frame class boilerplate
20 // =======================
22 NS_QUERYFRAME_HEAD(nsGridContainerFrame)
23 NS_QUERYFRAME_ENTRY(nsGridContainerFrame)
24 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
26 NS_IMPL_FRAMEARENA_HELPERS(nsGridContainerFrame)
28 nsContainerFrame*
29 NS_NewGridContainerFrame(nsIPresShell* aPresShell,
30 nsStyleContext* aContext)
32 return new (aPresShell) nsGridContainerFrame(aContext);
36 //----------------------------------------------------------------------
38 // nsGridContainerFrame Method Implementations
39 // ===========================================
41 void
42 nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
43 nsHTMLReflowMetrics& aDesiredSize,
44 const nsHTMLReflowState& aReflowState,
45 nsReflowStatus& aStatus)
47 DO_GLOBAL_REFLOW_COUNT("nsGridContainerFrame");
48 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
50 if (IsFrameTreeTooDeep(aReflowState, aDesiredSize, aStatus)) {
51 return;
54 #ifdef DEBUG
55 SanityCheckAnonymousGridItems();
56 #endif // DEBUG
58 LogicalMargin bp = aReflowState.ComputedLogicalBorderPadding();
59 bp.ApplySkipSides(GetLogicalSkipSides());
60 nscoord contentBSize = GetEffectiveComputedBSize(aReflowState);
61 if (contentBSize == NS_AUTOHEIGHT) {
62 contentBSize = 0;
64 WritingMode wm = aReflowState.GetWritingMode();
65 LogicalSize finalSize(wm,
66 aReflowState.ComputedISize() + bp.IStartEnd(wm),
67 contentBSize + bp.BStartEnd(wm));
68 aDesiredSize.SetSize(wm, finalSize);
69 aDesiredSize.SetOverflowAreasToDesiredBounds();
70 aStatus = NS_FRAME_COMPLETE;
71 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
74 nsIAtom*
75 nsGridContainerFrame::GetType() const
77 return nsGkAtoms::gridContainerFrame;
80 #ifdef DEBUG_FRAME_DUMP
81 nsresult
82 nsGridContainerFrame::GetFrameName(nsAString& aResult) const
84 return MakeFrameName(NS_LITERAL_STRING("GridContainer"), aResult);
86 #endif
88 #ifdef DEBUG
89 static bool
90 FrameWantsToBeInAnonymousGridItem(nsIFrame* aFrame)
92 // Note: This needs to match the logic in
93 // nsCSSFrameConstructor::FrameConstructionItem::NeedsAnonFlexOrGridItem()
94 return (aFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
95 nsGkAtoms::placeholderFrame == aFrame->GetType());
98 // Debugging method, to let us assert that our anonymous grid items are
99 // set up correctly -- in particular, we assert:
100 // (1) we don't have any inline non-replaced children
101 // (2) we don't have any consecutive anonymous grid items
102 // (3) we don't have any empty anonymous grid items
103 // (4) all children are on the expected child lists
104 void
105 nsGridContainerFrame::SanityCheckAnonymousGridItems() const
107 // XXX handle kOverflowContainersList / kExcessOverflowContainersList
108 // when we implement fragmentation?
109 ChildListIDs noCheckLists = kAbsoluteList | kFixedList;
110 ChildListIDs checkLists = kPrincipalList | kOverflowList;
111 for (nsIFrame::ChildListIterator childLists(this);
112 !childLists.IsDone(); childLists.Next()) {
113 if (!checkLists.Contains(childLists.CurrentID())) {
114 MOZ_ASSERT(noCheckLists.Contains(childLists.CurrentID()),
115 "unexpected non-empty child list");
116 continue;
119 bool prevChildWasAnonGridItem = false;
120 nsFrameList children = childLists.CurrentList();
121 for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
122 nsIFrame* child = e.get();
123 MOZ_ASSERT(!FrameWantsToBeInAnonymousGridItem(child),
124 "frame wants to be inside an anonymous grid item, "
125 "but it isn't");
126 if (child->StyleContext()->GetPseudo() ==
127 nsCSSAnonBoxes::anonymousGridItem) {
129 XXX haven't decided yet whether to reorder children or not.
130 XXX If we do, we want this assertion instead of the one below.
131 MOZ_ASSERT(!prevChildWasAnonGridItem ||
132 HasAnyStateBits(NS_STATE_GRID_CHILDREN_REORDERED),
133 "two anon grid items in a row (shouldn't happen, unless our "
134 "children have been reordered with the 'order' property)");
136 MOZ_ASSERT(!prevChildWasAnonGridItem, "two anon grid items in a row");
137 nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild();
138 MOZ_ASSERT(firstWrappedChild,
139 "anonymous grid item is empty (shouldn't happen)");
140 prevChildWasAnonGridItem = true;
141 } else {
142 prevChildWasAnonGridItem = false;
147 #endif // DEBUG