1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* base class #1 for rendering objects that have child lists */
9 #ifndef nsContainerFrame_h___
10 #define nsContainerFrame_h___
12 #include "mozilla/Attributes.h"
13 #include "LayoutConstants.h"
14 #include "nsISelectionDisplay.h"
15 #include "nsSplittableFrame.h"
16 #include "nsFrameList.h"
17 #include "nsLineBox.h"
18 #include "nsTHashSet.h"
20 class nsOverflowContinuationTracker
;
24 } // namespace mozilla
26 // Some macros for container classes to do sanity checking on
27 // width/height/x/y values computed during reflow.
28 // NOTE: AppUnitsPerCSSPixel value hardwired here to remove the
29 // dependency on nsDeviceContext.h. It doesn't matter if it's a
32 // 10 million pixels, converted to app units. Note that this a bit larger
33 // than 1/4 of nscoord_MAX. So, if any content gets to be this large, we're
34 // definitely in danger of grazing up against nscoord_MAX; hence, it's ABSURD.
35 # define ABSURD_COORD (10000000 * 60)
36 # define ABSURD_SIZE(_x) (((_x) < -ABSURD_COORD) || ((_x) > ABSURD_COORD))
40 * Implementation of a container frame.
42 class nsContainerFrame
: public nsSplittableFrame
{
44 NS_DECL_ABSTRACT_FRAME(nsContainerFrame
)
45 NS_DECL_QUERYFRAME_TARGET(nsContainerFrame
)
49 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
50 nsIFrame
* aPrevInFlow
) override
;
51 nsContainerFrame
* GetContentInsertionFrame() override
{ return this; }
53 const nsFrameList
& GetChildList(ChildListID aList
) const override
;
54 void GetChildLists(nsTArray
<ChildList
>* aLists
) const override
;
55 void Destroy(DestroyContext
&) override
;
57 void ChildIsDirty(nsIFrame
* aChild
) override
;
59 FrameSearchResult
PeekOffsetNoAmount(bool aForward
,
60 int32_t* aOffset
) override
;
61 FrameSearchResult
PeekOffsetCharacter(
62 bool aForward
, int32_t* aOffset
,
63 PeekOffsetCharacterOptions aOptions
=
64 PeekOffsetCharacterOptions()) override
;
66 #ifdef DEBUG_FRAME_DUMP
67 void List(FILE* out
= stderr
, const char* aPrefix
= "",
68 ListFlags aFlags
= ListFlags()) const override
;
69 void ListWithMatchedRules(FILE* out
= stderr
,
70 const char* aPrefix
= "") const override
;
71 void ListChildLists(FILE* aOut
, const char* aPrefix
, ListFlags aFlags
,
72 ChildListIDs aSkippedListIDs
) const;
73 virtual void ExtraContainerFrameInfo(nsACString
& aTo
) const;
76 // nsContainerFrame methods
79 * Called to set the initial list of frames. This happens after the frame
80 * has been initialized.
82 * This is only called once for a given child list, and won't be called
83 * at all for child lists with no initial list of frames.
85 * @param aListID the child list identifier.
86 * @param aChildList list of child frames. Each of the frames has its
87 * NS_FRAME_IS_DIRTY bit set. Must not be empty.
88 * This method cannot handle the child list returned by
89 * GetAbsoluteListID().
92 virtual void SetInitialChildList(ChildListID aListID
,
93 nsFrameList
&& aChildList
);
96 * This method is responsible for appending frames to the frame
97 * list. The implementation should append the frames to the specified
98 * child list and then generate a reflow command.
100 * @param aListID the child list identifier.
101 * @param aFrameList list of child frames to append. Each of the frames has
102 * its NS_FRAME_IS_DIRTY bit set. Must not be empty.
104 virtual void AppendFrames(ChildListID aListID
, nsFrameList
&& aFrameList
);
107 * This method is responsible for inserting frames into the frame
108 * list. The implementation should insert the new frames into the specified
109 * child list and then generate a reflow command.
111 * @param aListID the child list identifier.
112 * @param aPrevFrame the frame to insert frames <b>after</b>
113 * @param aPrevFrameLine (optional) if present (i.e., not null), the line
114 * box that aPrevFrame is part of.
115 * @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
116 * Each of the frames has its NS_FRAME_IS_DIRTY bit set
118 virtual void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
119 const nsLineList::iterator
* aPrevFrameLine
,
120 nsFrameList
&& aFrameList
);
123 * This method is responsible for removing a frame in the frame
124 * list. The implementation should do something with the removed frame
125 * and then generate a reflow command. The implementation is responsible
126 * for destroying the frame (the caller mustn't destroy it).
128 virtual void RemoveFrame(DestroyContext
&, ChildListID
, nsIFrame
*);
131 * Helper method to create next-in-flows if necessary. If aFrame
132 * already has a next-in-flow then this method does
133 * nothing. Otherwise, a new continuation frame is created and
134 * linked into the flow. In addition, the new frame is inserted
135 * into the principal child list after aFrame.
136 * @note calling this method on a block frame is illegal. Use
137 * nsBlockFrame::CreateContinuationFor() instead.
138 * @return the next-in-flow <b>if and only if</b> one is created. If
139 * a next-in-flow already exists, nullptr will be returned.
141 nsIFrame
* CreateNextInFlow(nsIFrame
* aFrame
);
144 * Delete aNextInFlow and its next-in-flows.
145 * @param aDeletingEmptyFrames if set, then the reflow for aNextInFlow's
146 * content was complete before aNextInFlow, so aNextInFlow and its
147 * next-in-flows no longer map any real content.
149 virtual void DeleteNextInFlowChild(DestroyContext
&, nsIFrame
* aNextInFlow
,
150 bool aDeletingEmptyFrames
);
152 // Positions the frame's view based on the frame's origin
153 static void PositionFrameView(nsIFrame
* aKidFrame
);
155 static void ReparentFrameView(nsIFrame
* aChildFrame
,
156 nsIFrame
* aOldParentFrame
,
157 nsIFrame
* aNewParentFrame
);
159 static void ReparentFrameViewList(const nsFrameList
& aChildFrameList
,
160 nsIFrame
* aOldParentFrame
,
161 nsIFrame
* aNewParentFrame
);
164 * Reparent aFrame from aOldParent to aNewParent.
166 static void ReparentFrame(nsIFrame
* aFrame
, nsContainerFrame
* aOldParent
,
167 nsContainerFrame
* aNewParent
);
170 * Reparent all the frames in aFrameList from aOldParent to aNewParent.
172 * Note: Reparenting a large frame list can be have huge performance impact.
173 * For example, instead of using this method, nsInlineFrame uses a "lazy
174 * reparenting" technique that it reparents a child frame just before
175 * reflowing the child. (See InlineReflowInput::mSetParentPointer.)
177 static void ReparentFrames(nsFrameList
& aFrameList
,
178 nsContainerFrame
* aOldParent
,
179 nsContainerFrame
* aNewParent
);
181 // Set the view's size and position after its frame has been reflowed.
182 static void SyncFrameViewAfterReflow(
183 nsPresContext
* aPresContext
, nsIFrame
* aFrame
, nsView
* aView
,
184 const nsRect
& aInkOverflowArea
,
185 ReflowChildFlags aFlags
= ReflowChildFlags::Default
);
188 * Converts the minimum and maximum sizes given in inner window app units to
189 * outer window device pixel sizes and assigns these constraints to the
192 * @param aPresContext pres context
193 * @param aWidget widget for this frame
194 * @param minimum size of the window in app units
195 * @param maxmimum size of the window in app units
197 static void SetSizeConstraints(nsPresContext
* aPresContext
,
198 nsIWidget
* aWidget
, const nsSize
& aMinSize
,
199 const nsSize
& aMaxSize
);
202 * Helper for calculating intrinsic inline size for inline containers.
204 * @param aData the intrinsic inline size data, either an InlineMinISizeData
205 * or an InlinePrefISizeData
206 * @param aHandleChildren a callback function invoked for each in-flow
207 * continuation, with the continuation frame and the intrinsic inline size
208 * data passed into it.
210 template <typename ISizeData
, typename F
>
211 void DoInlineIntrinsicISize(ISizeData
* aData
, F
& aHandleChildren
);
213 void DoInlineMinISize(gfxContext
* aRenderingContext
,
214 InlineMinISizeData
* aData
);
215 void DoInlinePrefISize(gfxContext
* aRenderingContext
,
216 InlinePrefISizeData
* aData
);
219 * This is the CSS block concept of computing 'auto' widths, which most
220 * classes derived from nsContainerFrame want.
222 virtual mozilla::LogicalSize
ComputeAutoSize(
223 gfxContext
* aRenderingContext
, mozilla::WritingMode aWM
,
224 const mozilla::LogicalSize
& aCBSize
, nscoord aAvailableISize
,
225 const mozilla::LogicalSize
& aMargin
,
226 const mozilla::LogicalSize
& aBorderPadding
,
227 const mozilla::StyleSizeOverrides
& aSizeOverrides
,
228 mozilla::ComputeSizeFlags aFlags
) override
;
231 * Positions aKidFrame and its view (if requested), and then calls Reflow().
232 * If the reflow status after reflowing the child is FullyComplete then any
233 * next-in-flows are deleted using DeleteNextInFlowChild().
235 * @param aReflowInput the reflow input for aKidFrame.
236 * @param aWM aPos's writing-mode (any writing mode will do).
237 * @param aPos Position of the aKidFrame to be moved, in terms of aWM.
238 * @param aContainerSize Size of the border-box of the containing frame.
240 * Note: If ReflowChildFlags::NoMoveFrame is requested, both aPos and
241 * aContainerSize are ignored.
243 void ReflowChild(nsIFrame
* aKidFrame
, nsPresContext
* aPresContext
,
244 ReflowOutput
& aDesiredSize
, const ReflowInput
& aReflowInput
,
245 const mozilla::WritingMode
& aWM
,
246 const mozilla::LogicalPoint
& aPos
,
247 const nsSize
& aContainerSize
, ReflowChildFlags aFlags
,
248 nsReflowStatus
& aStatus
,
249 nsOverflowContinuationTracker
* aTracker
= nullptr);
252 * The second half of frame reflow. Does the following:
253 * - sets the frame's bounds
254 * - sizes and positions (if requested) the frame's view. If the frame's final
255 * position differs from the current position and the frame itself does not
256 * have a view, then any child frames with views are positioned so they stay
258 * - sets the view's visibility, opacity, content transparency, and clip
259 * - invoked the DidReflow() function
261 * @param aReflowInput the reflow input for aKidFrame.
262 * @param aWM aPos's writing-mode (any writing mode will do).
263 * @param aPos Position of the aKidFrame to be moved, in terms of aWM.
264 * @param aContainerSize Size of the border-box of the containing frame.
266 * Note: If ReflowChildFlags::NoMoveFrame is requested, both aPos and
267 * aContainerSize are ignored unless
268 * ReflowChildFlags::ApplyRelativePositioning is requested.
270 static void FinishReflowChild(
271 nsIFrame
* aKidFrame
, nsPresContext
* aPresContext
,
272 const ReflowOutput
& aDesiredSize
, const ReflowInput
* aReflowInput
,
273 const mozilla::WritingMode
& aWM
, const mozilla::LogicalPoint
& aPos
,
274 const nsSize
& aContainerSize
, ReflowChildFlags aFlags
);
276 // XXX temporary: hold on to a copy of the old physical versions of
277 // ReflowChild and FinishReflowChild so that we can convert callers
279 void ReflowChild(nsIFrame
* aKidFrame
, nsPresContext
* aPresContext
,
280 ReflowOutput
& aDesiredSize
, const ReflowInput
& aReflowInput
,
281 nscoord aX
, nscoord aY
, ReflowChildFlags aFlags
,
282 nsReflowStatus
& aStatus
,
283 nsOverflowContinuationTracker
* aTracker
= nullptr);
285 static void FinishReflowChild(nsIFrame
* aKidFrame
,
286 nsPresContext
* aPresContext
,
287 const ReflowOutput
& aDesiredSize
,
288 const ReflowInput
* aReflowInput
, nscoord aX
,
289 nscoord aY
, ReflowChildFlags aFlags
);
291 static void PositionChildViews(nsIFrame
* aFrame
);
293 // ==========================================================================
294 /* Overflow containers are continuation frames that hold overflow. They
295 * are created when the frame runs out of computed block-size, but still has
296 * too much content to fit in the AvailableBSize. The parent creates a
297 * continuation as usual, but marks it as NS_FRAME_IS_OVERFLOW_CONTAINER
298 * and adds it to its next-in-flow's overflow container list, either by
299 * adding it directly or by putting it in its own excess overflow containers
300 * list (to be drained by the next-in-flow when it calls
301 * ReflowOverflowContainerChildren). The parent continues reflow as if
302 * the frame was complete once it ran out of computed block-size, but returns
303 * a reflow status with either IsIncomplete() or IsOverflowIncomplete() equal
304 * to true to request a next-in-flow. The parent's next-in-flow is then
305 * responsible for calling ReflowOverflowContainerChildren to (drain and)
306 * reflow these overflow continuations. Overflow containers do not affect
307 * other frames' size or position during reflow (but do affect their
308 * parent's overflow area).
310 * Overflow container continuations are different from normal continuations
312 * - more than one child of the frame can have its next-in-flow broken
313 * off and pushed into the frame's next-in-flow
314 * - new continuations may need to be spliced into the middle of the list
315 * or deleted continuations slipped out
316 * e.g. A, B, C are all fixed-size containers on one page, all have
317 * overflow beyond AvailableBSize, and content is dynamically added
319 * As a result, it is not possible to simply prepend the new continuations
320 * to the old list as with the OverflowProperty mechanism. To avoid
321 * complicated list splicing, the code assumes only one overflow containers
322 * list exists for a given frame: either its own OverflowContainersProperty
323 * or its prev-in-flow's ExcessOverflowContainersProperty, not both.
325 * The nsOverflowContinuationTracker helper class should be used for tracking
326 * overflow containers and adding them to the appropriate list.
327 * See nsBlockFrame::Reflow for a sample implementation.
329 * For more information, see https://wiki.mozilla.org/Gecko:Continuation_Model
331 * Note that Flex/GridContainerFrame doesn't use nsOverflowContinuationTracker
332 * so the above doesn't apply. Flex/Grid containers may have items that
333 * aren't in document order between fragments, due to the 'order' property,
334 * but they do maintain the invariant that children in the same nsFrameList
335 * are in document order. This means that when pushing/pulling items or
336 * merging lists, the result needs to be sorted to restore the order.
337 * However, given that lists are individually sorted, it's a simple merge
338 * operation of the two lists to make the result sorted.
339 * DrainExcessOverflowContainersList takes a merging function to perform that
340 * operation. (By "document order" here we mean normal frame tree order,
341 * which is approximately flattened DOM tree order.)
344 friend class nsOverflowContinuationTracker
;
346 typedef void (*ChildFrameMerger
)(nsFrameList
& aDest
, nsFrameList
& aSrc
,
347 nsContainerFrame
* aParent
);
348 static inline void DefaultChildFrameMerge(nsFrameList
& aDest
,
350 nsContainerFrame
* aParent
) {
351 aDest
.AppendFrames(nullptr, std::move(aSrc
));
355 * Reflow overflow container children. They are invisible to normal reflow
356 * (i.e. don't affect sizing or placement of other children) and inherit
357 * width and horizontal position from their prev-in-flow.
360 * 1. Pulls excess overflow containers from the prev-in-flow and adds
361 * them to our overflow container list
362 * 2. Reflows all our overflow container kids
363 * 3. Expands aOverflowRect as necessary to accomodate these children.
364 * 4. Sets aStatus's mOverflowIncomplete flag (along with
365 * mNextInFlowNeedsReflow as necessary) if any overflow children
367 * 5. Prepends a list of their continuations to our excess overflow
368 * container list, to be drained into our next-in-flow when it is
371 * The caller is responsible for tracking any new overflow container
372 * continuations it makes, removing them from its child list, and
373 * making sure they are stored properly in the overflow container lists.
374 * The nsOverflowContinuationTracker helper class should be used for this.
376 * @param aFlags is passed through to ReflowChild
377 * @param aMergeFunc is passed to DrainExcessOverflowContainersList
378 * @param aContainerSize is used only for converting logical coordinate to
379 * physical coordinate. If a tentative container size is used, caller
380 * may need to adjust the position of our overflow container children
381 * once the real size is known if our writing mode is vertical-rl.
383 void ReflowOverflowContainerChildren(
384 nsPresContext
* aPresContext
, const ReflowInput
& aReflowInput
,
385 mozilla::OverflowAreas
& aOverflowRects
, ReflowChildFlags aFlags
,
386 nsReflowStatus
& aStatus
,
387 ChildFrameMerger aMergeFunc
= DefaultChildFrameMerge
,
388 Maybe
<nsSize
> aContainerSize
= Nothing());
391 * Move any frames on our overflow list to the end of our principal list.
392 * @return true if there were any overflow frames
394 virtual bool DrainSelfOverflowList() override
;
397 * Move all frames on our prev-in-flow's and our own ExcessOverflowContainers
398 * lists to our OverflowContainers list. If there are frames on multiple
399 * lists they are merged using aMergeFunc.
400 * @return a pointer to our OverflowContainers list, if any
402 nsFrameList
* DrainExcessOverflowContainersList(
403 ChildFrameMerger aMergeFunc
= DefaultChildFrameMerge
);
406 * Removes aChild without destroying it and without requesting reflow.
407 * Continuations are not affected. Checks the principal and overflow lists,
408 * and also the [excess] overflow containers lists if the frame bit
409 * NS_FRAME_IS_OVERFLOW_CONTAINER is set. It does not check any other lists.
410 * aChild must be in one of the above mentioned lists, or an assertion is
413 * Note: This method can destroy either overflow list or [excess] overflow
414 * containers list if aChild is the only child in the list. Any pointer to the
415 * list obtained prior to calling this method shouldn't be used.
417 virtual void StealFrame(nsIFrame
* aChild
);
420 * Removes the next-siblings of aChild without destroying them and without
421 * requesting reflow. Checks the principal and overflow lists (not
422 * overflow containers / excess overflow containers). Does not check any
423 * other auxiliary lists.
424 * @param aChild a child frame or nullptr
425 * @return If aChild is non-null, the next-siblings of aChild, if any.
426 * If aChild is null, all child frames on the principal list, if any.
428 nsFrameList
StealFramesAfter(nsIFrame
* aChild
);
431 * Add overflow containers to the display list
433 void DisplayOverflowContainers(nsDisplayListBuilder
* aBuilder
,
434 const nsDisplayListSet
& aLists
);
437 * Builds display lists for the children. The background
438 * of each child is placed in the Content() list (suitable for inline
439 * children and other elements that behave like inlines,
440 * but not for in-flow block children of blocks). DOES NOT
441 * paint the background/borders/outline of this frame. This should
442 * probably be avoided and eventually removed. It's currently here
443 * to emulate what nsContainerFrame::Paint did.
445 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
446 const nsDisplayListSet
& aLists
) override
;
448 static void PlaceFrameView(nsIFrame
* aFrame
) {
449 if (aFrame
->HasView())
450 nsContainerFrame::PositionFrameView(aFrame
);
452 nsContainerFrame::PositionChildViews(aFrame
);
456 * Returns a CSS Box Alignment constant which the caller can use to align
457 * the absolutely-positioned child (whose ReflowInput is aChildRI) within
458 * a CSS Box Alignment area associated with this container.
460 * The lower 8 bits of the returned value are guaranteed to form a valid
461 * argument for CSSAlignUtils::AlignJustifySelf(). (The upper 8 bits may
462 * encode an <overflow-position>.)
464 * NOTE: This default nsContainerFrame implementation is a stub, and isn't
465 * meant to be called. Subclasses must provide their own implementations, if
466 * they use CSS Box Alignment to determine the static position of their
467 * absolutely-positioned children. (Though: if subclasses share enough code,
468 * maybe this nsContainerFrame impl should include some shared code.)
470 * @param aChildRI A ReflowInput for the positioned child frame that's being
472 * @param aLogicalAxis The axis (of this container frame) in which the caller
473 * would like to align the child frame.
475 virtual mozilla::StyleAlignFlags
CSSAlignmentForAbsPosChild(
476 const ReflowInput
& aChildRI
, mozilla::LogicalAxis aLogicalAxis
) const;
478 #define NS_DECLARE_FRAME_PROPERTY_FRAMELIST(prop) \
479 NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, nsFrameList)
481 using FrameListPropertyDescriptor
=
482 mozilla::FrameProperties::Descriptor
<nsFrameList
>;
484 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowProperty
)
485 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowContainersProperty
)
486 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(ExcessOverflowContainersProperty
)
487 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(BackdropProperty
)
489 // Only really used on nsBlockFrame instances, but the caller thinks it could
490 // have arbitrary nsContainerFrames.
491 NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(FirstLetterProperty
, nsIFrame
)
493 void SetHasFirstLetterChild() { mHasFirstLetterChild
= true; }
495 void ClearHasFirstLetterChild() { mHasFirstLetterChild
= false; }
498 // Use this to suppress the ABSURD_SIZE assertions.
499 NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize
, bool)
500 bool IsAbsurdSizeAssertSuppressed() const {
501 return GetProperty(DebugReflowingWithInfiniteISize());
505 // Incorporate the child overflow areas into aOverflowAreas.
506 // If the child does not have a overflow, use the child area.
507 void ConsiderChildOverflow(mozilla::OverflowAreas
& aOverflowAreas
,
508 nsIFrame
* aChildFrame
);
511 nsContainerFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
,
513 : nsSplittableFrame(aStyle
, aPresContext
, aID
) {}
518 * Helper for DestroyFrom. DestroyAbsoluteFrames is called before
519 * destroying frames on lists that can contain placeholders.
520 * Derived classes must do that too, if they destroy such frame lists.
521 * See nsBlockFrame::DestroyFrom for an example.
523 void DestroyAbsoluteFrames(DestroyContext
&);
526 * Helper for StealFrame. Returns true if aChild was removed from its list.
528 bool MaybeStealOverflowContainerFrame(nsIFrame
* aChild
);
531 * Builds a display list for non-block children that behave like
532 * inlines. This puts the background of each child into the
533 * Content() list (suitable for inline children but not for
534 * in-flow block children of blocks).
535 * @param aForcePseudoStack forces each child into a pseudo-stacking-context
536 * so its background and all other display items (except for positioned
537 * display items) go into the Content() list.
539 void BuildDisplayListForNonBlockChildren(nsDisplayListBuilder
* aBuilder
,
540 const nsDisplayListSet
& aLists
,
541 DisplayChildFlags aFlags
= {});
544 * A version of BuildDisplayList that use DisplayChildFlag::Inline.
545 * Intended as a convenience for derived classes.
547 void BuildDisplayListForInline(nsDisplayListBuilder
* aBuilder
,
548 const nsDisplayListSet
& aLists
) {
549 DisplayBorderBackgroundOutline(aBuilder
, aLists
);
550 BuildDisplayListForNonBlockChildren(aBuilder
, aLists
,
551 DisplayChildFlag::Inline
);
554 // ==========================================================================
555 /* Overflow Frames are frames that did not fit and must be pulled by
556 * our next-in-flow during its reflow. (The same concept for overflow
557 * containers is called "excess frames". We should probably make the
562 * Get the frames on the overflow list, overflow containers list, or excess
563 * overflow containers list. Can return null if there are no frames in the
566 * The caller does NOT take ownership of the list; it's still owned by this
567 * frame. A non-null return value indicates that the list is non-empty.
569 [[nodiscard
]] nsFrameList
* GetOverflowFrames() const {
570 nsFrameList
* list
= GetProperty(OverflowProperty());
571 NS_ASSERTION(!list
|| !list
->IsEmpty(), "Unexpected empty overflow list");
574 [[nodiscard
]] nsFrameList
* GetOverflowContainers() const {
575 nsFrameList
* list
= GetProperty(OverflowContainersProperty());
576 NS_ASSERTION(!list
|| !list
->IsEmpty(),
577 "Unexpected empty overflow containers list");
580 [[nodiscard
]] nsFrameList
* GetExcessOverflowContainers() const {
581 nsFrameList
* list
= GetProperty(ExcessOverflowContainersProperty());
582 NS_ASSERTION(!list
|| !list
->IsEmpty(),
583 "Unexpected empty overflow containers list");
588 * Same as the Get methods above, but also remove and the property from this
591 * The caller is responsible for deleting nsFrameList and either passing
592 * ownership of the frames to someone else or destroying the frames. A
593 * non-null return value indicates that the list is non-empty. The recommended
594 * way to use this function it to assign its return value into an
597 [[nodiscard
]] nsFrameList
* StealOverflowFrames() {
598 nsFrameList
* list
= TakeProperty(OverflowProperty());
599 NS_ASSERTION(!list
|| !list
->IsEmpty(), "Unexpected empty overflow list");
602 [[nodiscard
]] nsFrameList
* StealOverflowContainers() {
603 nsFrameList
* list
= TakeProperty(OverflowContainersProperty());
604 NS_ASSERTION(!list
|| !list
->IsEmpty(), "Unexpected empty overflow list");
607 [[nodiscard
]] nsFrameList
* StealExcessOverflowContainers() {
608 nsFrameList
* list
= TakeProperty(ExcessOverflowContainersProperty());
609 NS_ASSERTION(!list
|| !list
->IsEmpty(), "Unexpected empty overflow list");
614 * Set the overflow list, overflow containers list, or excess overflow
615 * containers list. The argument must be a *non-empty* list.
617 * After this operation, the argument becomes an empty list.
619 * @return the frame list associated with the property.
621 nsFrameList
* SetOverflowFrames(nsFrameList
&& aOverflowFrames
) {
622 MOZ_ASSERT(aOverflowFrames
.NotEmpty(), "Shouldn't be called");
623 auto* list
= new (PresShell()) nsFrameList(std::move(aOverflowFrames
));
624 SetProperty(OverflowProperty(), list
);
627 nsFrameList
* SetOverflowContainers(nsFrameList
&& aOverflowContainers
) {
628 MOZ_ASSERT(aOverflowContainers
.NotEmpty(), "Shouldn't set an empty list!");
629 MOZ_ASSERT(!GetProperty(OverflowContainersProperty()),
630 "Shouldn't override existing list!");
631 MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers
),
632 "This type of frame can't have overflow containers!");
633 auto* list
= new (PresShell()) nsFrameList(std::move(aOverflowContainers
));
634 SetProperty(OverflowContainersProperty(), list
);
637 nsFrameList
* SetExcessOverflowContainers(
638 nsFrameList
&& aExcessOverflowContainers
) {
639 MOZ_ASSERT(aExcessOverflowContainers
.NotEmpty(),
640 "Shouldn't set an empty list!");
641 MOZ_ASSERT(!GetProperty(ExcessOverflowContainersProperty()),
642 "Shouldn't override existing list!");
643 MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers
),
644 "This type of frame can't have overflow containers!");
646 new (PresShell()) nsFrameList(std::move(aExcessOverflowContainers
));
647 SetProperty(ExcessOverflowContainersProperty(), list
);
652 * Destroy the overflow list, overflow containers list, or excess overflow
655 * The list to be destroyed must be empty. That is, the caller is responsible
656 * for either passing ownership of the frames to someone else or destroying
657 * the frames before calling these methods.
659 void DestroyOverflowList() {
660 nsFrameList
* list
= TakeProperty(OverflowProperty());
661 MOZ_ASSERT(list
&& list
->IsEmpty());
662 list
->Delete(PresShell());
664 void DestroyOverflowContainers() {
665 nsFrameList
* list
= TakeProperty(OverflowContainersProperty());
666 MOZ_ASSERT(list
&& list
->IsEmpty());
667 list
->Delete(PresShell());
669 void DestroyExcessOverflowContainers() {
670 nsFrameList
* list
= TakeProperty(ExcessOverflowContainersProperty());
671 MOZ_ASSERT(list
&& list
->IsEmpty());
672 list
->Delete(PresShell());
676 * Moves any frames on both the prev-in-flow's overflow list and the
677 * receiver's overflow to the receiver's child list.
679 * Resets the overlist pointers to nullptr, and updates the receiver's child
680 * count and content mapping.
682 * @return true if any frames were moved and false otherwise
684 bool MoveOverflowToChildList();
687 * Merge a sorted frame list into our overflow list. aList becomes empty after
690 void MergeSortedOverflow(nsFrameList
& aList
);
693 * Merge a sorted frame list into our excess overflow containers list. aList
694 * becomes empty after this call.
696 void MergeSortedExcessOverflowContainers(nsFrameList
& aList
);
699 * Moves all frames from aSrc into aDest such that the resulting aDest
700 * is still sorted in document content order and continuation order. aSrc
701 * becomes empty after this call.
703 * Precondition: both |aSrc| and |aDest| must be sorted to begin with.
704 * @param aCommonAncestor a hint for nsLayoutUtils::CompareTreePosition
706 static void MergeSortedFrameLists(nsFrameList
& aDest
, nsFrameList
& aSrc
,
707 nsIContent
* aCommonAncestor
);
710 * This is intended to be used as a ChildFrameMerger argument for
711 * ReflowOverflowContainerChildren() and DrainExcessOverflowContainersList().
713 static inline void MergeSortedFrameListsFor(nsFrameList
& aDest
,
715 nsContainerFrame
* aParent
) {
716 MergeSortedFrameLists(aDest
, aSrc
, aParent
->GetContent());
720 * Basically same as MoveOverflowToChildList, except that this is for
721 * handling inline children where children of prev-in-flow can be
722 * pushed to overflow list even if a next-in-flow exists.
724 * @param aLineContainer the line container of the current frame.
726 * @return true if any frames were moved and false otherwise
728 bool MoveInlineOverflowToChildList(nsIFrame
* aLineContainer
);
731 * Push aFromChild and its next siblings to the overflow list.
733 * @param aFromChild the first child frame to push. It is disconnected
735 * @param aPrevSibling aFrameChild's previous sibling. Must not be null.
736 * It's an error to push a parent's first child frame.
738 void PushChildrenToOverflow(nsIFrame
* aFromChild
, nsIFrame
* aPrevSibling
);
741 * Same as above, except that this pushes frames to the next-in-flow
742 * frame and changes the geometric parent of the pushed frames when
743 * there is a next-in-flow frame.
745 * Updates the next-in-flow's child count. Does <b>not</b> update the
746 * pusher's child count.
748 void PushChildren(nsIFrame
* aFromChild
, nsIFrame
* aPrevSibling
);
751 * Iterate our children in our principal child list in the normal document
752 * order, and append them (or their next-in-flows) to either our overflow list
753 * or excess overflow container list according to their presence in
754 * aPushedItems, aIncompleteItems, or aOverflowIncompleteItems.
756 * Note: This method is only intended for Grid / Flex containers.
757 * aPushedItems, aIncompleteItems, and aOverflowIncompleteItems are expected
758 * to contain only Grid / Flex items. That is, they should contain only
761 * @return true if any items are moved; false otherwise.
763 using FrameHashtable
= nsTHashSet
<nsIFrame
*>;
764 bool PushIncompleteChildren(const FrameHashtable
& aPushedItems
,
765 const FrameHashtable
& aIncompleteItems
,
766 const FrameHashtable
& aOverflowIncompleteItems
);
769 * Prepare our child lists so that they are ready to reflow by the following
772 * - Merge overflow list from our prev-in-flow into our principal child list.
773 * - Merge our own overflow list into our principal child list,
774 * - Push any child's next-in-flows in our principal child list to our
776 * - Pull up any first-in-flow child we might have pushed from our
779 void NormalizeChildLists();
782 * Helper to implement AppendFrames / InsertFrames for flex / grid
785 void NoteNewChildren(ChildListID aListID
, const nsFrameList
& aFrameList
);
788 * Helper to implement DrainSelfOverflowList() for flex / grid containers.
790 bool DrainAndMergeSelfOverflowList();
793 * Helper to find the first non-anonymous-box frame in the subtree rooted at
796 static nsIFrame
* GetFirstNonAnonBoxInSubtree(nsIFrame
* aFrame
);
799 * Reparent floats whose placeholders are inline descendants of aFrame from
800 * whatever block they're currently parented by to aOurBlock.
801 * @param aReparentSiblings if this is true, we follow aFrame's
802 * GetNextSibling chain reparenting them all
804 static void ReparentFloatsForInlineChild(nsIFrame
* aOurBlock
,
806 bool aReparentSiblings
);
809 * Try to remove aChildToRemove from the frame list stored in aProp.
810 * If aChildToRemove was removed from the aProp list and that list became
811 * empty, then aProp is removed from this frame and deleted.
812 * @note if aChildToRemove isn't on the aProp frame list, it might still be
813 * removed from whatever list it happens to be on, so use this method
814 * carefully. This method is primarily meant for removing frames from the
815 * [Excess]OverflowContainers lists.
816 * @return true if aChildToRemove was removed from some list
818 bool TryRemoveFrame(FrameListPropertyDescriptor aProp
,
819 nsIFrame
* aChildToRemove
);
821 // ==========================================================================
823 * Convenience methods for traversing continuations
826 struct ContinuationTraversingState
{
827 nsContainerFrame
* mNextInFlow
;
828 explicit ContinuationTraversingState(nsContainerFrame
* aFrame
)
829 : mNextInFlow(static_cast<nsContainerFrame
*>(aFrame
->GetNextInFlow())) {
834 * Find the first frame that is a child of this frame's next-in-flows,
835 * considering both their principal child lists and overflow lists.
837 nsIFrame
* GetNextInFlowChild(ContinuationTraversingState
& aState
,
838 bool* aIsInOverflow
= nullptr);
841 * Remove the result of GetNextInFlowChild from its current parent and
842 * append it to this frame's principal child list.
844 nsIFrame
* PullNextInFlowChild(ContinuationTraversingState
& aState
);
847 * Safely destroy the frames on the nsFrameList stored on aProp for this
848 * frame then remove the property and delete the frame list.
849 * Nothing happens if the property doesn't exist.
851 void SafelyDestroyFrameListProp(DestroyContext
&,
852 mozilla::PresShell
* aPresShell
,
853 FrameListPropertyDescriptor aProp
);
855 // ==========================================================================
857 // Helper used by Progress and Meter frames. Returns true if the bar should
858 // be rendered vertically, based on writing-mode and -moz-orient properties.
859 bool ResolvedOrientationIsVertical();
862 * Calculate the used values for 'width' and 'height' for a replaced element.
863 * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
865 * @param aAspectRatio the aspect ratio calculated by GetAspectRatio().
867 mozilla::LogicalSize
ComputeSizeWithIntrinsicDimensions(
868 gfxContext
* aRenderingContext
, mozilla::WritingMode aWM
,
869 const mozilla::IntrinsicSize
& aIntrinsicSize
,
870 const mozilla::AspectRatio
& aAspectRatio
,
871 const mozilla::LogicalSize
& aCBSize
, const mozilla::LogicalSize
& aMargin
,
872 const mozilla::LogicalSize
& aBorderPadding
,
873 const mozilla::StyleSizeOverrides
& aSizeOverrides
,
874 mozilla::ComputeSizeFlags aFlags
);
876 // Compute tight bounds assuming this frame honours its border, background
877 // and outline, its children's tight bounds, and nothing else.
878 nsRect
ComputeSimpleTightBounds(mozilla::gfx::DrawTarget
* aDrawTarget
) const;
881 * If this frame is dirty, marks all absolutely-positioned children of this
882 * frame dirty. If this frame isn't dirty, or if there are no
883 * absolutely-positioned children, does nothing.
885 * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
886 * reflow this frame's absolutely-positioned children after the dirty bit on
887 * this frame has already been cleared, which prevents ReflowInput from
888 * propagating the dirty bit normally. This situation generally only arises
889 * when a multipass layout algorithm is used.
891 void PushDirtyBitToAbsoluteFrames();
893 // Helper function that tests if the frame tree is too deep; if it is
894 // it marks the frame as "unflowable", zeroes out the metrics, sets
895 // the reflow status, and returns true. Otherwise, the frame is
896 // unmarked "unflowable" and the metrics and reflow status are not
897 // touched and false is returned.
898 bool IsFrameTreeTooDeep(const ReflowInput
& aReflowInput
,
899 ReflowOutput
& aMetrics
, nsReflowStatus
& aStatus
);
902 * @return true if we should avoid a page/column break in this frame.
904 bool ShouldAvoidBreakInside(const ReflowInput
& aReflowInput
) const;
907 * To be called by |BuildDisplayLists| of this class or derived classes to add
908 * a translucent overlay if this frame's content is selected.
909 * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
910 * which kind of content this is for
912 void DisplaySelectionOverlay(
913 nsDisplayListBuilder
* aBuilder
, nsDisplayList
* aList
,
914 uint16_t aContentType
= nsISelectionDisplay::DISPLAY_FRAMES
);
916 // ==========================================================================
919 // A helper for flex / grid container to sanity check child lists before
920 // reflow. Intended to be called after calling NormalizeChildLists().
921 void SanityCheckChildListsBeforeReflow() const;
923 // A helper to set mDidPushItemsBitMayLie if needed. Intended to be called
924 // only in flex / grid container's RemoveFrame.
925 void SetDidPushItemsBitIfNeeded(ChildListID aListID
, nsIFrame
* aOldFrame
);
927 // A flag for flex / grid containers. If true, NS_STATE_GRID_DID_PUSH_ITEMS or
928 // NS_STATE_FLEX_DID_PUSH_ITEMS may be set even though all pushed frames may
929 // have been removed. This is used to suppress an assertion in case
930 // RemoveFrame removed all associated child frames.
931 bool mDidPushItemsBitMayLie
{false};
937 // ==========================================================================
938 /* The out-of-flow-related code below is for a hacky way of splitting
939 * absolutely-positioned frames. Basically what we do is split the frame
940 * in nsAbsoluteContainingBlock and pretend the continuation is an overflow
941 * container. This isn't an ideal solution, but it lets us print the content
942 * at least. See bug 154892.
946 * Helper class for tracking overflow container continuations during reflow.
948 * A frame is related to two sets of overflow containers: those that /are/
949 * its own children, and those that are /continuations/ of its children.
950 * This tracker walks through those continuations (the frame's NIF's children)
951 * and their prev-in-flows (a subset of the frame's normal and overflow
952 * container children) in parallel. It allows the reflower to synchronously
953 * walk its overflow continuations while it loops through and reflows its
954 * children. This makes it possible to insert new continuations at the correct
955 * place in the overflow containers list.
957 * The reflower is expected to loop through its children in the same order it
958 * looped through them the last time (if there was a last time).
959 * For each child, the reflower should either
960 * - call Skip for the child if was not reflowed in this pass
961 * - call Insert for the overflow continuation if the child was reflowed
962 * but has incomplete overflow
963 * - call Finished for the child if it was reflowed in this pass but
964 * is either complete or has a normal next-in-flow. This call can
965 * be skipped if the child did not previously have an overflow
968 class nsOverflowContinuationTracker
{
971 * Initializes an nsOverflowContinuationTracker to help track overflow
972 * continuations of aFrame's children. Typically invoked on 'this'.
974 * aWalkOOFFrames determines whether the walker skips out-of-flow frames
975 * or skips non-out-of-flow frames.
977 * Don't set aSkipOverflowContainerChildren to false unless you plan
978 * to walk your own overflow container children. (Usually they are handled
979 * by calling ReflowOverflowContainerChildren.) aWalkOOFFrames is ignored
980 * if aSkipOverflowContainerChildren is false.
982 nsOverflowContinuationTracker(nsContainerFrame
* aFrame
, bool aWalkOOFFrames
,
983 bool aSkipOverflowContainerChildren
= true);
985 * This function adds an overflow continuation to our running list and
986 * sets its NS_FRAME_IS_OVERFLOW_CONTAINER flag.
988 * aReflowStatus should preferably be specific to the recently-reflowed
989 * child and not influenced by any of its siblings' statuses. This
990 * function sets the NS_FRAME_IS_DIRTY bit on aOverflowCont if it needs
991 * to be reflowed. (Its need for reflow depends on changes to its
992 * prev-in-flow, not to its parent--for whom it is invisible, reflow-wise.)
994 * The caller MUST disconnect the frame from its parent's child list
995 * if it was not previously an NS_FRAME_IS_OVERFLOW_CONTAINER (because
996 * StealFrame is much more inefficient than disconnecting in place
997 * during Reflow, which the caller is able to do but we are not).
999 * The caller MUST NOT disconnect the frame from its parent's
1000 * child list if it is already an NS_FRAME_IS_OVERFLOW_CONTAINER.
1001 * (In this case we will disconnect and reconnect it ourselves.)
1003 nsresult
Insert(nsIFrame
* aOverflowCont
, nsReflowStatus
& aReflowStatus
);
1005 * Begin/EndFinish() must be called for each child that is reflowed
1006 * but no longer has an overflow continuation. (It may be called for
1007 * other children, but in that case has no effect.) It increments our
1008 * walker and makes sure we drop any dangling pointers to its
1009 * next-in-flow. This function MUST be called before stealing or
1010 * deleting aChild's next-in-flow.
1011 * The AutoFinish helper object does that for you. Use it like so:
1012 * if (kidNextInFlow) {
1013 * nsOverflowContinuationTracker::AutoFinish fini(tracker, kid);
1014 * ... DeleteNextInFlowChild/StealFrame(kidNextInFlow) here ...
1017 class MOZ_RAII AutoFinish
{
1019 AutoFinish(nsOverflowContinuationTracker
* aTracker
, nsIFrame
* aChild
)
1020 : mTracker(aTracker
), mChild(aChild
) {
1021 if (mTracker
) mTracker
->BeginFinish(mChild
);
1024 if (mTracker
) mTracker
->EndFinish(mChild
);
1028 nsOverflowContinuationTracker
* mTracker
;
1033 * This function should be called for each child that isn't reflowed.
1034 * It increments our walker and sets the mOverflowIncomplete
1035 * reflow flag if it encounters an overflow continuation so that our
1036 * next-in-flow doesn't get prematurely deleted. It MUST be called on
1037 * each unreflowed child that has an overflow container continuation;
1038 * it MAY be called on other children, but it isn't necessary (doesn't
1041 void Skip(nsIFrame
* aChild
, nsReflowStatus
& aReflowStatus
) {
1042 MOZ_ASSERT(aChild
, "null ptr");
1043 if (aChild
== mSentry
) {
1045 if (aReflowStatus
.IsComplete()) {
1046 aReflowStatus
.SetOverflowIncomplete();
1053 * @see class AutoFinish
1055 void BeginFinish(nsIFrame
* aChild
);
1056 void EndFinish(nsIFrame
* aChild
);
1058 void SetupOverflowContList();
1059 void SetUpListWalker();
1062 /* We hold a pointer to either the next-in-flow's overflow containers list
1063 or, if that doesn't exist, our frame's excess overflow containers list.
1064 We need to make sure that we drop that pointer if the list becomes
1065 empty and is deleted elsewhere. */
1066 nsFrameList
* mOverflowContList
;
1067 /* We hold a pointer to the most recently-reflowed child that has an
1068 overflow container next-in-flow. We do this because it's a known
1069 good point; this pointer won't be deleted on us. We can use it to
1070 recover our place in the list. */
1071 nsIFrame
* mPrevOverflowCont
;
1072 /* This is a pointer to the next overflow container's prev-in-flow, which
1073 is (or should be) a child of our frame. When we hit this, we will need
1074 to increment this walker to the next overflow container. */
1076 /* Parent of all frames in mOverflowContList. If our mOverflowContList
1077 is an excessOverflowContainersProperty, or null, then this is our frame
1078 (the frame that was passed in to our constructor). Otherwise this is
1079 that frame's next-in-flow, and our mOverflowContList is mParent's
1080 overflowContainersProperty */
1081 nsContainerFrame
* mParent
;
1082 /* Tells SetUpListWalker whether or not to walk us past any continuations
1083 of overflow containers. aWalkOOFFrames is ignored when this is false. */
1084 bool mSkipOverflowContainerChildren
;
1085 /* Tells us whether to pay attention to OOF frames or non-OOF frames */
1086 bool mWalkOOFFrames
;
1089 // Start Display Reflow Debugging
1093 DR_cookie(nsPresContext
* aPresContext
, nsIFrame
* aFrame
,
1094 const mozilla::ReflowInput
& aReflowInput
,
1095 mozilla::ReflowOutput
& aMetrics
, nsReflowStatus
& aStatus
);
1097 void Change() const;
1099 nsPresContext
* mPresContext
;
1101 const mozilla::ReflowInput
& mReflowInput
;
1102 mozilla::ReflowOutput
& mMetrics
;
1103 nsReflowStatus
& mStatus
;
1107 struct DR_layout_cookie
{
1108 explicit DR_layout_cookie(nsIFrame
* aFrame
);
1109 ~DR_layout_cookie();
1115 struct DR_intrinsic_inline_size_cookie
{
1116 DR_intrinsic_inline_size_cookie(nsIFrame
* aFrame
, const char* aType
,
1118 ~DR_intrinsic_inline_size_cookie();
1126 struct DR_intrinsic_size_cookie
{
1127 DR_intrinsic_size_cookie(nsIFrame
* aFrame
, const char* aType
,
1129 ~DR_intrinsic_size_cookie();
1137 struct DR_init_constraints_cookie
{
1138 DR_init_constraints_cookie(
1139 nsIFrame
* aFrame
, mozilla::ReflowInput
* aState
, nscoord aCBWidth
,
1140 nscoord aCBHeight
, const mozilla::Maybe
<mozilla::LogicalMargin
> aBorder
,
1141 const mozilla::Maybe
<mozilla::LogicalMargin
> aPadding
);
1142 ~DR_init_constraints_cookie();
1145 mozilla::ReflowInput
* mState
;
1149 struct DR_init_offsets_cookie
{
1150 DR_init_offsets_cookie(nsIFrame
* aFrame
,
1151 mozilla::SizeComputationInput
* aState
,
1152 nscoord aPercentBasis
,
1153 mozilla::WritingMode aCBWritingMode
,
1154 const mozilla::Maybe
<mozilla::LogicalMargin
> aBorder
,
1155 const mozilla::Maybe
<mozilla::LogicalMargin
> aPadding
);
1156 ~DR_init_offsets_cookie();
1159 mozilla::SizeComputationInput
* mState
;
1163 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1164 dr_rf_metrics, dr_rf_status) \
1165 DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, \
1167 # define DISPLAY_REFLOW_CHANGE() dr_cookie.Change();
1168 # define DISPLAY_LAYOUT(dr_frame) DR_layout_cookie dr_cookie(dr_frame);
1169 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1170 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1171 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1172 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1173 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
1174 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1175 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
1176 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1177 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
1178 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
1179 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1181 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
1183 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1185 DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_pb, dr_cbwm, \
1190 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1191 dr_rf_metrics, dr_rf_status)
1192 # define DISPLAY_REFLOW_CHANGE()
1193 # define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
1194 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1195 PR_BEGIN_MACRO PR_END_MACRO
1196 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1197 PR_BEGIN_MACRO PR_END_MACRO
1198 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1199 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1200 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1201 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1203 PR_BEGIN_MACRO PR_END_MACRO
1204 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1206 PR_BEGIN_MACRO PR_END_MACRO
1209 // End Display Reflow Debugging
1211 #endif /* nsContainerFrame_h___ */