Bug 1867925 - Mark some storage-access-api tests as intermittent after wpt-sync....
[gecko.git] / layout / generic / nsContainerFrame.h
blob09f6cf76f5cae5d5a2fbd56ef694a95e60327d7c
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;
22 namespace mozilla {
23 class PresShell;
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
30 // little off.
31 #ifdef DEBUG
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))
37 #endif
39 /**
40 * Implementation of a container frame.
42 class nsContainerFrame : public nsSplittableFrame {
43 public:
44 NS_DECL_ABSTRACT_FRAME(nsContainerFrame)
45 NS_DECL_QUERYFRAME_TARGET(nsContainerFrame)
46 NS_DECL_QUERYFRAME
48 // nsIFrame overrides
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;
74 #endif
76 // nsContainerFrame methods
78 /**
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().
90 * @see #Init()
92 virtual void SetInitialChildList(ChildListID aListID,
93 nsFrameList&& aChildList);
95 /**
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
190 * widget.
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
257 * in sync
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
278 // incrementally.
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
311 * in that
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
318 * and removed from B
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,
349 nsFrameList& aSrc,
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.
359 * This method
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
366 * are incomplete and
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
369 * reflowed.
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
411 * triggered.
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);
451 else
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
471 * aligned.
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; }
497 #ifdef DEBUG
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());
503 #endif
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);
510 protected:
511 nsContainerFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
512 ClassID aID)
513 : nsSplittableFrame(aStyle, aPresContext, aID) {}
515 ~nsContainerFrame();
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
558 * names match.)
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
564 * list.
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");
572 return list;
574 [[nodiscard]] nsFrameList* GetOverflowContainers() const {
575 nsFrameList* list = GetProperty(OverflowContainersProperty());
576 NS_ASSERTION(!list || !list->IsEmpty(),
577 "Unexpected empty overflow containers list");
578 return list;
580 [[nodiscard]] nsFrameList* GetExcessOverflowContainers() const {
581 nsFrameList* list = GetProperty(ExcessOverflowContainersProperty());
582 NS_ASSERTION(!list || !list->IsEmpty(),
583 "Unexpected empty overflow containers list");
584 return list;
588 * Same as the Get methods above, but also remove and the property from this
589 * frame.
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
595 * AutoFrameListPtr.
597 [[nodiscard]] nsFrameList* StealOverflowFrames() {
598 nsFrameList* list = TakeProperty(OverflowProperty());
599 NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
600 return list;
602 [[nodiscard]] nsFrameList* StealOverflowContainers() {
603 nsFrameList* list = TakeProperty(OverflowContainersProperty());
604 NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
605 return list;
607 [[nodiscard]] nsFrameList* StealExcessOverflowContainers() {
608 nsFrameList* list = TakeProperty(ExcessOverflowContainersProperty());
609 NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
610 return 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);
625 return 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(CanContainOverflowContainers(),
632 "This type of frame can't have overflow containers!");
633 auto* list = new (PresShell()) nsFrameList(std::move(aOverflowContainers));
634 SetProperty(OverflowContainersProperty(), list);
635 return 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(CanContainOverflowContainers(),
644 "This type of frame can't have overflow containers!");
645 auto* list =
646 new (PresShell()) nsFrameList(std::move(aExcessOverflowContainers));
647 SetProperty(ExcessOverflowContainersProperty(), list);
648 return list;
652 * Destroy the overflow list, overflow containers list, or excess overflow
653 * containers list.
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
688 * this call.
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,
714 nsFrameList& aSrc,
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
734 * from aPrevSibling
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 * Iterate our children in our principal child list in the normal document
742 * order, and append them (or their next-in-flows) to either our overflow list
743 * or excess overflow container list according to their presence in
744 * aPushedItems, aIncompleteItems, or aOverflowIncompleteItems.
746 * Note: This method is only intended for Grid / Flex containers.
747 * aPushedItems, aIncompleteItems, and aOverflowIncompleteItems are expected
748 * to contain only Grid / Flex items. That is, they should contain only
749 * in-flow children.
751 * @return true if any items are moved; false otherwise.
753 using FrameHashtable = nsTHashSet<nsIFrame*>;
754 bool PushIncompleteChildren(const FrameHashtable& aPushedItems,
755 const FrameHashtable& aIncompleteItems,
756 const FrameHashtable& aOverflowIncompleteItems);
759 * Prepare our child lists so that they are ready to reflow by the following
760 * operations:
762 * - Merge overflow list from our prev-in-flow into our principal child list.
763 * - Merge our own overflow list into our principal child list,
764 * - Push any child's next-in-flows in our principal child list to our
765 * overflow list.
766 * - Pull up any first-in-flow child we might have pushed from our
767 * next-in-flows.
769 void NormalizeChildLists();
772 * Helper to implement AppendFrames / InsertFrames for flex / grid
773 * containers.
775 void NoteNewChildren(ChildListID aListID, const nsFrameList& aFrameList);
778 * Helper to implement DrainSelfOverflowList() for flex / grid containers.
780 bool DrainAndMergeSelfOverflowList();
783 * Helper to find the first non-anonymous-box frame in the subtree rooted at
784 * aFrame.
786 static nsIFrame* GetFirstNonAnonBoxInSubtree(nsIFrame* aFrame);
789 * Reparent floats whose placeholders are inline descendants of aFrame from
790 * whatever block they're currently parented by to aOurBlock.
791 * @param aReparentSiblings if this is true, we follow aFrame's
792 * GetNextSibling chain reparenting them all
794 static void ReparentFloatsForInlineChild(nsIFrame* aOurBlock,
795 nsIFrame* aFrame,
796 bool aReparentSiblings);
799 * Try to remove aChildToRemove from the frame list stored in aProp.
800 * If aChildToRemove was removed from the aProp list and that list became
801 * empty, then aProp is removed from this frame and deleted.
802 * @note if aChildToRemove isn't on the aProp frame list, it might still be
803 * removed from whatever list it happens to be on, so use this method
804 * carefully. This method is primarily meant for removing frames from the
805 * [Excess]OverflowContainers lists.
806 * @return true if aChildToRemove was removed from some list
808 bool TryRemoveFrame(FrameListPropertyDescriptor aProp,
809 nsIFrame* aChildToRemove);
811 // ==========================================================================
813 * Convenience methods for traversing continuations
816 struct ContinuationTraversingState {
817 nsContainerFrame* mNextInFlow;
818 explicit ContinuationTraversingState(nsContainerFrame* aFrame)
819 : mNextInFlow(static_cast<nsContainerFrame*>(aFrame->GetNextInFlow())) {
824 * Find the first frame that is a child of this frame's next-in-flows,
825 * considering both their principal child lists and overflow lists.
827 nsIFrame* GetNextInFlowChild(ContinuationTraversingState& aState,
828 bool* aIsInOverflow = nullptr);
831 * Remove the result of GetNextInFlowChild from its current parent and
832 * append it to this frame's principal child list.
834 nsIFrame* PullNextInFlowChild(ContinuationTraversingState& aState);
837 * Safely destroy the frames on the nsFrameList stored on aProp for this
838 * frame then remove the property and delete the frame list.
839 * Nothing happens if the property doesn't exist.
841 void SafelyDestroyFrameListProp(DestroyContext&,
842 mozilla::PresShell* aPresShell,
843 FrameListPropertyDescriptor aProp);
845 // ==========================================================================
847 // Helper used by Progress and Meter frames. Returns true if the bar should
848 // be rendered vertically, based on writing-mode and -moz-orient properties.
849 bool ResolvedOrientationIsVertical();
852 * Calculate the used values for 'width' and 'height' for a replaced element.
853 * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
855 * @param aAspectRatio the aspect ratio calculated by GetAspectRatio().
857 mozilla::LogicalSize ComputeSizeWithIntrinsicDimensions(
858 gfxContext* aRenderingContext, mozilla::WritingMode aWM,
859 const mozilla::IntrinsicSize& aIntrinsicSize,
860 const mozilla::AspectRatio& aAspectRatio,
861 const mozilla::LogicalSize& aCBSize, const mozilla::LogicalSize& aMargin,
862 const mozilla::LogicalSize& aBorderPadding,
863 const mozilla::StyleSizeOverrides& aSizeOverrides,
864 mozilla::ComputeSizeFlags aFlags);
866 // Compute tight bounds assuming this frame honours its border, background
867 // and outline, its children's tight bounds, and nothing else.
868 nsRect ComputeSimpleTightBounds(mozilla::gfx::DrawTarget* aDrawTarget) const;
871 * If this frame is dirty, marks all absolutely-positioned children of this
872 * frame dirty. If this frame isn't dirty, or if there are no
873 * absolutely-positioned children, does nothing.
875 * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
876 * reflow this frame's absolutely-positioned children after the dirty bit on
877 * this frame has already been cleared, which prevents ReflowInput from
878 * propagating the dirty bit normally. This situation generally only arises
879 * when a multipass layout algorithm is used.
881 void PushDirtyBitToAbsoluteFrames();
883 // Helper function that tests if the frame tree is too deep; if it is
884 // it marks the frame as "unflowable", zeroes out the metrics, sets
885 // the reflow status, and returns true. Otherwise, the frame is
886 // unmarked "unflowable" and the metrics and reflow status are not
887 // touched and false is returned.
888 bool IsFrameTreeTooDeep(const ReflowInput& aReflowInput,
889 ReflowOutput& aMetrics, nsReflowStatus& aStatus);
892 * @return true if we should avoid a page/column break in this frame.
894 bool ShouldAvoidBreakInside(const ReflowInput& aReflowInput) const;
897 * To be called by |BuildDisplayLists| of this class or derived classes to add
898 * a translucent overlay if this frame's content is selected.
899 * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
900 * which kind of content this is for
902 void DisplaySelectionOverlay(
903 nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
904 uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
906 // ==========================================================================
908 #ifdef DEBUG
909 // A helper for flex / grid container to sanity check child lists before
910 // reflow. Intended to be called after calling NormalizeChildLists().
911 void SanityCheckChildListsBeforeReflow() const;
913 // A helper to set mDidPushItemsBitMayLie if needed. Intended to be called
914 // only in flex / grid container's RemoveFrame.
915 void SetDidPushItemsBitIfNeeded(ChildListID aListID, nsIFrame* aOldFrame);
917 // A flag for flex / grid containers. If true, NS_STATE_GRID_DID_PUSH_ITEMS or
918 // NS_STATE_FLEX_DID_PUSH_ITEMS may be set even though all pushed frames may
919 // have been removed. This is used to suppress an assertion in case
920 // RemoveFrame removed all associated child frames.
921 bool mDidPushItemsBitMayLie{false};
922 #endif
924 nsFrameList mFrames;
927 // ==========================================================================
928 /* The out-of-flow-related code below is for a hacky way of splitting
929 * absolutely-positioned frames. Basically what we do is split the frame
930 * in nsAbsoluteContainingBlock and pretend the continuation is an overflow
931 * container. This isn't an ideal solution, but it lets us print the content
932 * at least. See bug 154892.
936 * Helper class for tracking overflow container continuations during reflow.
938 * A frame is related to two sets of overflow containers: those that /are/
939 * its own children, and those that are /continuations/ of its children.
940 * This tracker walks through those continuations (the frame's NIF's children)
941 * and their prev-in-flows (a subset of the frame's normal and overflow
942 * container children) in parallel. It allows the reflower to synchronously
943 * walk its overflow continuations while it loops through and reflows its
944 * children. This makes it possible to insert new continuations at the correct
945 * place in the overflow containers list.
947 * The reflower is expected to loop through its children in the same order it
948 * looped through them the last time (if there was a last time).
949 * For each child, the reflower should either
950 * - call Skip for the child if was not reflowed in this pass
951 * - call Insert for the overflow continuation if the child was reflowed
952 * but has incomplete overflow
953 * - call Finished for the child if it was reflowed in this pass but
954 * is either complete or has a normal next-in-flow. This call can
955 * be skipped if the child did not previously have an overflow
956 * continuation.
958 class nsOverflowContinuationTracker {
959 public:
961 * Initializes an nsOverflowContinuationTracker to help track overflow
962 * continuations of aFrame's children. Typically invoked on 'this'.
964 * aWalkOOFFrames determines whether the walker skips out-of-flow frames
965 * or skips non-out-of-flow frames.
967 * Don't set aSkipOverflowContainerChildren to false unless you plan
968 * to walk your own overflow container children. (Usually they are handled
969 * by calling ReflowOverflowContainerChildren.) aWalkOOFFrames is ignored
970 * if aSkipOverflowContainerChildren is false.
972 nsOverflowContinuationTracker(nsContainerFrame* aFrame, bool aWalkOOFFrames,
973 bool aSkipOverflowContainerChildren = true);
975 * This function adds an overflow continuation to our running list and
976 * sets its NS_FRAME_IS_OVERFLOW_CONTAINER flag.
978 * aReflowStatus should preferably be specific to the recently-reflowed
979 * child and not influenced by any of its siblings' statuses. This
980 * function sets the NS_FRAME_IS_DIRTY bit on aOverflowCont if it needs
981 * to be reflowed. (Its need for reflow depends on changes to its
982 * prev-in-flow, not to its parent--for whom it is invisible, reflow-wise.)
984 * The caller MUST disconnect the frame from its parent's child list
985 * if it was not previously an NS_FRAME_IS_OVERFLOW_CONTAINER (because
986 * StealFrame is much more inefficient than disconnecting in place
987 * during Reflow, which the caller is able to do but we are not).
989 * The caller MUST NOT disconnect the frame from its parent's
990 * child list if it is already an NS_FRAME_IS_OVERFLOW_CONTAINER.
991 * (In this case we will disconnect and reconnect it ourselves.)
993 nsresult Insert(nsIFrame* aOverflowCont, nsReflowStatus& aReflowStatus);
995 * Begin/EndFinish() must be called for each child that is reflowed
996 * but no longer has an overflow continuation. (It may be called for
997 * other children, but in that case has no effect.) It increments our
998 * walker and makes sure we drop any dangling pointers to its
999 * next-in-flow. This function MUST be called before stealing or
1000 * deleting aChild's next-in-flow.
1001 * The AutoFinish helper object does that for you. Use it like so:
1002 * if (kidNextInFlow) {
1003 * nsOverflowContinuationTracker::AutoFinish fini(tracker, kid);
1004 * ... DeleteNextInFlowChild/StealFrame(kidNextInFlow) here ...
1007 class MOZ_RAII AutoFinish {
1008 public:
1009 AutoFinish(nsOverflowContinuationTracker* aTracker, nsIFrame* aChild)
1010 : mTracker(aTracker), mChild(aChild) {
1011 if (mTracker) mTracker->BeginFinish(mChild);
1013 ~AutoFinish() {
1014 if (mTracker) mTracker->EndFinish(mChild);
1017 private:
1018 nsOverflowContinuationTracker* mTracker;
1019 nsIFrame* mChild;
1023 * This function should be called for each child that isn't reflowed.
1024 * It increments our walker and sets the mOverflowIncomplete
1025 * reflow flag if it encounters an overflow continuation so that our
1026 * next-in-flow doesn't get prematurely deleted. It MUST be called on
1027 * each unreflowed child that has an overflow container continuation;
1028 * it MAY be called on other children, but it isn't necessary (doesn't
1029 * do anything).
1031 void Skip(nsIFrame* aChild, nsReflowStatus& aReflowStatus) {
1032 MOZ_ASSERT(aChild, "null ptr");
1033 if (aChild == mSentry) {
1034 StepForward();
1035 if (aReflowStatus.IsComplete()) {
1036 aReflowStatus.SetOverflowIncomplete();
1041 private:
1043 * @see class AutoFinish
1045 void BeginFinish(nsIFrame* aChild);
1046 void EndFinish(nsIFrame* aChild);
1048 void SetupOverflowContList();
1049 void SetUpListWalker();
1050 void StepForward();
1052 /* We hold a pointer to either the next-in-flow's overflow containers list
1053 or, if that doesn't exist, our frame's excess overflow containers list.
1054 We need to make sure that we drop that pointer if the list becomes
1055 empty and is deleted elsewhere. */
1056 nsFrameList* mOverflowContList;
1057 /* We hold a pointer to the most recently-reflowed child that has an
1058 overflow container next-in-flow. We do this because it's a known
1059 good point; this pointer won't be deleted on us. We can use it to
1060 recover our place in the list. */
1061 nsIFrame* mPrevOverflowCont;
1062 /* This is a pointer to the next overflow container's prev-in-flow, which
1063 is (or should be) a child of our frame. When we hit this, we will need
1064 to increment this walker to the next overflow container. */
1065 nsIFrame* mSentry;
1066 /* Parent of all frames in mOverflowContList. If our mOverflowContList
1067 is an excessOverflowContainersProperty, or null, then this is our frame
1068 (the frame that was passed in to our constructor). Otherwise this is
1069 that frame's next-in-flow, and our mOverflowContList is mParent's
1070 overflowContainersProperty */
1071 nsContainerFrame* mParent;
1072 /* Tells SetUpListWalker whether or not to walk us past any continuations
1073 of overflow containers. aWalkOOFFrames is ignored when this is false. */
1074 bool mSkipOverflowContainerChildren;
1075 /* Tells us whether to pay attention to OOF frames or non-OOF frames */
1076 bool mWalkOOFFrames;
1079 // Start Display Reflow Debugging
1080 #ifdef DEBUG
1082 struct DR_cookie {
1083 DR_cookie(nsPresContext* aPresContext, nsIFrame* aFrame,
1084 const mozilla::ReflowInput& aReflowInput,
1085 mozilla::ReflowOutput& aMetrics, nsReflowStatus& aStatus);
1086 ~DR_cookie();
1087 void Change() const;
1089 nsPresContext* mPresContext;
1090 nsIFrame* mFrame;
1091 const mozilla::ReflowInput& mReflowInput;
1092 mozilla::ReflowOutput& mMetrics;
1093 nsReflowStatus& mStatus;
1094 void* mValue;
1097 struct DR_layout_cookie {
1098 explicit DR_layout_cookie(nsIFrame* aFrame);
1099 ~DR_layout_cookie();
1101 nsIFrame* mFrame;
1102 void* mValue;
1105 struct DR_intrinsic_inline_size_cookie {
1106 DR_intrinsic_inline_size_cookie(nsIFrame* aFrame, const char* aType,
1107 nscoord& aResult);
1108 ~DR_intrinsic_inline_size_cookie();
1110 nsIFrame* mFrame;
1111 const char* mType;
1112 nscoord& mResult;
1113 void* mValue;
1116 struct DR_intrinsic_size_cookie {
1117 DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
1118 nsSize& aResult);
1119 ~DR_intrinsic_size_cookie();
1121 nsIFrame* mFrame;
1122 const char* mType;
1123 nsSize& mResult;
1124 void* mValue;
1127 struct DR_init_constraints_cookie {
1128 DR_init_constraints_cookie(
1129 nsIFrame* aFrame, mozilla::ReflowInput* aState, nscoord aCBWidth,
1130 nscoord aCBHeight, const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
1131 const mozilla::Maybe<mozilla::LogicalMargin> aPadding);
1132 ~DR_init_constraints_cookie();
1134 nsIFrame* mFrame;
1135 mozilla::ReflowInput* mState;
1136 void* mValue;
1139 struct DR_init_offsets_cookie {
1140 DR_init_offsets_cookie(nsIFrame* aFrame,
1141 mozilla::SizeComputationInput* aState,
1142 nscoord aPercentBasis,
1143 mozilla::WritingMode aCBWritingMode,
1144 const mozilla::Maybe<mozilla::LogicalMargin> aBorder,
1145 const mozilla::Maybe<mozilla::LogicalMargin> aPadding);
1146 ~DR_init_offsets_cookie();
1148 nsIFrame* mFrame;
1149 mozilla::SizeComputationInput* mState;
1150 void* mValue;
1153 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1154 dr_rf_metrics, dr_rf_status) \
1155 DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, \
1156 dr_rf_status);
1157 # define DISPLAY_REFLOW_CHANGE() dr_cookie.Change();
1158 # define DISPLAY_LAYOUT(dr_frame) DR_layout_cookie dr_cookie(dr_frame);
1159 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1160 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1161 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1162 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1163 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
1164 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1165 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
1166 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1167 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
1168 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
1169 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1170 dr_pad) \
1171 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
1172 dr_bdr, dr_pad)
1173 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1174 dr_pad) \
1175 DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_pb, dr_cbwm, \
1176 dr_bdr, dr_pad)
1178 #else
1180 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1181 dr_rf_metrics, dr_rf_status)
1182 # define DISPLAY_REFLOW_CHANGE()
1183 # define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
1184 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1185 PR_BEGIN_MACRO PR_END_MACRO
1186 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1187 PR_BEGIN_MACRO PR_END_MACRO
1188 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1189 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1190 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1191 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1192 dr_pad) \
1193 PR_BEGIN_MACRO PR_END_MACRO
1194 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1195 dr_pad) \
1196 PR_BEGIN_MACRO PR_END_MACRO
1198 #endif
1199 // End Display Reflow Debugging
1201 #endif /* nsContainerFrame_h___ */