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/. */
6
7 /* base class #1 for rendering objects that have child lists */
8
9 #ifndef nsContainerFrame_h___
10 #define nsContainerFrame_h___
11
12 #include "mozilla/Attributes.h"
13 #include "nsSplittableFrame.h"
14 #include "nsFrameList.h"
15 #include "nsLayoutUtils.h"
16 #include "nsLineBox.h"
17
18 class nsOverflowContinuationTracker;
19
20 namespace mozilla {
21 class PresShell;
22 } // namespace mozilla
23
24 // Some macros for container classes to do sanity checking on
25 // width/height/x/y values computed during reflow.
26 // NOTE: AppUnitsPerCSSPixel value hardwired here to remove the
27 // dependency on nsDeviceContext.h. It doesn't matter if it's a
28 // little off.
29 #ifdef DEBUG
30 // 10 million pixels, converted to app units. Note that this a bit larger
31 // than 1/4 of nscoord_MAX. So, if any content gets to be this large, we're
32 // definitely in danger of grazing up against nscoord_MAX; hence, it's CRAZY.
33 # define CRAZY_COORD (10000000 * 60)
34 # define CRAZY_SIZE(_x) (((_x) < -CRAZY_COORD) || ((_x) > CRAZY_COORD))
35 #endif
36
37 /**
38 * Implementation of a container frame.
39 */
40 class nsContainerFrame : public nsSplittableFrame {
41 public:
42 NS_DECL_ABSTRACT_FRAME(nsContainerFrame)
43 NS_DECL_QUERYFRAME_TARGET(nsContainerFrame)
44 NS_DECL_QUERYFRAME
45
46 // nsIFrame overrides
47 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
48 nsIFrame* aPrevInFlow) override;
GetContentInsertionFrame()49 virtual nsContainerFrame* GetContentInsertionFrame() override { return this; }
50
51 virtual const nsFrameList& GetChildList(ChildListID aList) const override;
52 virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
53 virtual void DestroyFrom(nsIFrame* aDestructRoot,
54 PostDestroyData& aPostDestroyData) override;
55 virtual void ChildIsDirty(nsIFrame* aChild) override;
56
57 virtual FrameSearchResult PeekOffsetNoAmount(bool aForward,
58 int32_t* aOffset) override;
59 virtual FrameSearchResult PeekOffsetCharacter(
60 bool aForward, int32_t* aOffset,
61 PeekOffsetCharacterOptions aOptions =
62 PeekOffsetCharacterOptions()) override;
63
64 #ifdef DEBUG_FRAME_DUMP
65 void List(FILE* out = stderr, const char* aPrefix = "",
66 ListFlags aFlags = ListFlags()) const override;
67 void ListWithMatchedRules(FILE* out = stderr,
68 const char* aPrefix = "") const override;
69 virtual void ExtraContainerFrameInfo(nsACString& aTo) const;
70 #endif
71
72 // nsContainerFrame methods
73
74 /**
75 * Called to set the initial list of frames. This happens after the frame
76 * has been initialized.
77 *
78 * This is only called once for a given child list, and won't be called
79 * at all for child lists with no initial list of frames.
80 *
81 * @param aListID the child list identifier.
82 * @param aChildList list of child frames. Each of the frames has its
83 * NS_FRAME_IS_DIRTY bit set. Must not be empty.
84 * This method cannot handle the child list returned by
85 * GetAbsoluteListID().
86 * @see #Init()
87 */
88 virtual void SetInitialChildList(ChildListID aListID,
89 nsFrameList& aChildList);
90
91 /**
92 * This method is responsible for appending frames to the frame
93 * list. The implementation should append the frames to the specified
94 * child list and then generate a reflow command.
95 *
96 * @param aListID the child list identifier.
97 * @param aFrameList list of child frames to append. Each of the frames has
98 * its NS_FRAME_IS_DIRTY bit set. Must not be empty.
99 */
100 virtual void AppendFrames(ChildListID aListID, nsFrameList& aFrameList);
101
102 /**
103 * This method is responsible for inserting frames into the frame
104 * list. The implementation should insert the new frames into the specified
105 * child list and then generate a reflow command.
106 *
107 * @param aListID the child list identifier.
108 * @param aPrevFrame the frame to insert frames <b>after</b>
109 * @param aPrevFrameLine (optional) if present (i.e., not null), the line
110 * box that aPrevFrame is part of.
111 * @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
112 * Each of the frames has its NS_FRAME_IS_DIRTY bit set
113 */
114 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
115 const nsLineList::iterator* aPrevFrameLine,
116 nsFrameList& aFrameList);
117
118 /**
119 * This method is responsible for removing a frame in the frame
120 * list. The implementation should do something with the removed frame
121 * and then generate a reflow command. The implementation is responsible
122 * for destroying aOldFrame (the caller mustn't destroy aOldFrame).
123 *
124 * @param aListID the child list identifier.
125 * @param aOldFrame the frame to remove
126 */
127 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame);
128
129 /**
130 * Helper method to create next-in-flows if necessary. If aFrame
131 * already has a next-in-flow then this method does
132 * nothing. Otherwise, a new continuation frame is created and
133 * linked into the flow. In addition, the new frame is inserted
134 * into the principal child list after aFrame.
135 * @note calling this method on a block frame is illegal. Use
136 * nsBlockFrame::CreateContinuationFor() instead.
137 * @return the next-in-flow <b>if and only if</b> one is created. If
138 * a next-in-flow already exists, nullptr will be returned.
139 */
140 nsIFrame* CreateNextInFlow(nsIFrame* aFrame);
141
142 /**
143 * Delete aNextInFlow and its next-in-flows.
144 * @param aDeletingEmptyFrames if set, then the reflow for aNextInFlow's
145 * content was complete before aNextInFlow, so aNextInFlow and its
146 * next-in-flows no longer map any real content.
147 */
148 virtual void DeleteNextInFlowChild(nsIFrame* aNextInFlow,
149 bool aDeletingEmptyFrames);
150
151 // Positions the frame's view based on the frame's origin
152 static void PositionFrameView(nsIFrame* aKidFrame);
153
154 static nsresult ReparentFrameView(nsIFrame* aChildFrame,
155 nsIFrame* aOldParentFrame,
156 nsIFrame* aNewParentFrame);
157
158 static void ReparentFrameViewList(const nsFrameList& aChildFrameList,
159 nsIFrame* aOldParentFrame,
160 nsIFrame* aNewParentFrame);
161
162 /**
163 * Reparent aFrame from aOldParent to aNewParent.
164 */
165 static void ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent,
166 nsContainerFrame* aNewParent);
167
168 /**
169 * Reparent all the frames in aFrameList from aOldParent to aNewParent.
170 *
171 * Note: Reparenting a large frame list can be have huge performance impact.
172 * For example, instead of using this method, nsInlineFrame uses a "lazy
173 * reparenting" technique that it reparents a child frame just before
174 * reflowing the child. (See InlineReflowInput::mSetParentPointer.)
175 */
176 static void ReparentFrames(nsFrameList& aFrameList,
177 nsContainerFrame* aOldParent,
178 nsContainerFrame* aNewParent);
179
180 // Set the view's size and position after its frame has been reflowed.
181 static void SyncFrameViewAfterReflow(
182 nsPresContext* aPresContext, nsIFrame* aFrame, nsView* aView,
183 const nsRect& aVisualOverflowArea,
184 ReflowChildFlags aFlags = ReflowChildFlags::Default);
185
186 // Syncs properties to the top level view and window, like transparency and
187 // shadow.
188 // The SET_ASYNC indicates that the actual nsIWidget calls to sync the window
189 // properties should be done async.
190 enum {
191 SET_ASYNC = 0x01,
192 };
193 static void SyncWindowProperties(nsPresContext* aPresContext,
194 nsIFrame* aFrame, nsView* aView,
195 gfxContext* aRC, uint32_t aFlags);
196
197 /**
198 * Converts the minimum and maximum sizes given in inner window app units to
199 * outer window device pixel sizes and assigns these constraints to the
200 * widget.
201 *
202 * @param aPresContext pres context
203 * @param aWidget widget for this frame
204 * @param minimum size of the window in app units
205 * @param maxmimum size of the window in app units
206 */
207 static void SetSizeConstraints(nsPresContext* aPresContext,
208 nsIWidget* aWidget, const nsSize& aMinSize,
209 const nsSize& aMaxSize);
210
211 // Used by both nsInlineFrame and nsFirstLetterFrame.
212 void DoInlineIntrinsicISize(gfxContext* aRenderingContext,
213 InlineIntrinsicISizeData* aData,
214 nsLayoutUtils::IntrinsicISizeType aType);
215
216 /**
217 * This is the CSS block concept of computing 'auto' widths, which most
218 * classes derived from nsContainerFrame want.
219 */
220 virtual mozilla::LogicalSize ComputeAutoSize(
221 gfxContext* aRenderingContext, mozilla::WritingMode aWM,
222 const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize,
223 const mozilla::LogicalSize& aMargin, const mozilla::LogicalSize& aBorder,
224 const mozilla::LogicalSize& aPadding, ComputeSizeFlags aFlags) override;
225
226 /**
227 * Positions aKidFrame and its view (if requested), and then calls Reflow().
228 * If the reflow status after reflowing the child is FullyComplete then any
229 * next-in-flows are deleted using DeleteNextInFlowChild().
230 *
231 * @param aReflowInput the reflow input for aKidFrame.
232 * @param aWM aPos's writing-mode (any writing mode will do).
233 * @param aPos Position of the aKidFrame to be moved, in terms of aWM.
234 * @param aContainerSize Size of the border-box of the containing frame.
235 *
236 * Note: If ReflowChildFlags::NoMoveFrame is requested, both aPos and
237 * aContainerSize are ignored.
238 */
239 void ReflowChild(nsIFrame* aKidFrame, nsPresContext* aPresContext,
240 ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput,
241 const mozilla::WritingMode& aWM,
242 const mozilla::LogicalPoint& aPos,
243 const nsSize& aContainerSize, ReflowChildFlags aFlags,
244 nsReflowStatus& aStatus,
245 nsOverflowContinuationTracker* aTracker = nullptr);
246
247 /**
248 * The second half of frame reflow. Does the following:
249 * - sets the frame's bounds
250 * - sizes and positions (if requested) the frame's view. If the frame's final
251 * position differs from the current position and the frame itself does not
252 * have a view, then any child frames with views are positioned so they stay
253 * in sync
254 * - sets the view's visibility, opacity, content transparency, and clip
255 * - invoked the DidReflow() function
256 *
257 * @param aReflowInput the reflow input for aKidFrame.
258 * @param aWM aPos's writing-mode (any writing mode will do).
259 * @param aPos Position of the aKidFrame to be moved, in terms of aWM.
260 * @param aContainerSize Size of the border-box of the containing frame.
261 *
262 * Note: If ReflowChildFlags::NoMoveFrame is requested, both aPos and
263 * aContainerSize are ignored unless
264 * ReflowChildFlags::ApplyRelativePositioning is requested.
265 */
266 static void FinishReflowChild(
267 nsIFrame* aKidFrame, nsPresContext* aPresContext,
268 const ReflowOutput& aDesiredSize, const ReflowInput* aReflowInput,
269 const mozilla::WritingMode& aWM, const mozilla::LogicalPoint& aPos,
270 const nsSize& aContainerSize, ReflowChildFlags aFlags);
271
272 // XXX temporary: hold on to a copy of the old physical versions of
273 // ReflowChild and FinishReflowChild so that we can convert callers
274 // incrementally.
275 void ReflowChild(nsIFrame* aKidFrame, nsPresContext* aPresContext,
276 ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput,
277 nscoord aX, nscoord aY, ReflowChildFlags aFlags,
278 nsReflowStatus& aStatus,
279 nsOverflowContinuationTracker* aTracker = nullptr);
280
281 static void FinishReflowChild(nsIFrame* aKidFrame,
282 nsPresContext* aPresContext,
283 const ReflowOutput& aDesiredSize,
284 const ReflowInput* aReflowInput, nscoord aX,
285 nscoord aY, ReflowChildFlags aFlags);
286
287 static void PositionChildViews(nsIFrame* aFrame);
288
289 // ==========================================================================
290 /* Overflow containers are continuation frames that hold overflow. They
291 * are created when the frame runs out of computed height, but still has
292 * too much content to fit in the availableHeight. The parent creates a
293 * continuation as usual, but marks it as NS_FRAME_IS_OVERFLOW_CONTAINER
294 * and adds it to its next-in-flow's overflow container list, either by
295 * adding it directly or by putting it in its own excess overflow containers
296 * list (to be drained by the next-in-flow when it calls
297 * ReflowOverflowContainerChildren). The parent continues reflow as if
298 * the frame was complete once it ran out of computed height, but returns a
299 * reflow status with either IsIncomplete() or IsOverflowIncomplete() equal
300 * to true to request a next-in-flow. The parent's next-in-flow is then
301 * responsible for calling ReflowOverflowContainerChildren to (drain and)
302 * reflow these overflow continuations. Overflow containers do not affect
303 * other frames' size or position during reflow (but do affect their
304 * parent's overflow area).
305 *
306 * Overflow container continuations are different from normal continuations
307 * in that
308 * - more than one child of the frame can have its next-in-flow broken
309 * off and pushed into the frame's next-in-flow
310 * - new continuations may need to be spliced into the middle of the list
311 * or deleted continuations slipped out
312 * e.g. A, B, C are all fixed-size containers on one page, all have
313 * overflow beyond availableHeight, and content is dynamically added
314 * and removed from B
315 * As a result, it is not possible to simply prepend the new continuations
316 * to the old list as with the overflowProperty mechanism. To avoid
317 * complicated list splicing, the code assumes only one overflow containers
318 * list exists for a given frame: either its own overflowContainersProperty
319 * or its prev-in-flow's excessOverflowContainersProperty, not both.
320 *
321 * The nsOverflowContinuationTracker helper class should be used for tracking
322 * overflow containers and adding them to the appropriate list.
323 * See nsBlockFrame::Reflow for a sample implementation.
324 *
325 * For more information, see https://wiki.mozilla.org/Gecko:Continuation_Model
326 */
327
328 friend class nsOverflowContinuationTracker;
329
330 typedef void (*ChildFrameMerger)(nsFrameList& aDest, nsFrameList& aSrc,
331 nsContainerFrame* aParent);
DefaultChildFrameMerge(nsFrameList & aDest,nsFrameList & aSrc,nsContainerFrame * aParent)332 static inline void DefaultChildFrameMerge(nsFrameList& aDest,
333 nsFrameList& aSrc,
334 nsContainerFrame* aParent) {
335 aDest.AppendFrames(nullptr, aSrc);
336 }
337
338 /**
339 * Reflow overflow container children. They are invisible to normal reflow
340 * (i.e. don't affect sizing or placement of other children) and inherit
341 * width and horizontal position from their prev-in-flow.
342 *
343 * This method
344 * 1. Pulls excess overflow containers from the prev-in-flow and adds
345 * them to our overflow container list
346 * 2. Reflows all our overflow container kids
347 * 3. Expands aOverflowRect as necessary to accomodate these children.
348 * 4. Sets aStatus's mOverflowIncomplete flag (along with
349 * mNextInFlowNeedsReflow as necessary) if any overflow children
350 * are incomplete and
351 * 5. Prepends a list of their continuations to our excess overflow
352 * container list, to be drained into our next-in-flow when it is
353 * reflowed.
354 *
355 * The caller is responsible for tracking any new overflow container
356 * continuations it makes, removing them from its child list, and
357 * making sure they are stored properly in the overflow container lists.
358 * The nsOverflowContinuationTracker helper class should be used for this.
359 *
360 * @param aFlags is passed through to ReflowChild
361 * @param aMergeFunc is passed to DrainExcessOverflowContainersList
362 */
363 void ReflowOverflowContainerChildren(
364 nsPresContext* aPresContext, const ReflowInput& aReflowInput,
365 nsOverflowAreas& aOverflowRects, ReflowChildFlags aFlags,
366 nsReflowStatus& aStatus,
367 ChildFrameMerger aMergeFunc = DefaultChildFrameMerge);
368
369 /**
370 * Move any frames on our overflow list to the end of our principal list.
371 * @return true if there were any overflow frames
372 */
373 virtual bool DrainSelfOverflowList() override;
374
375 /**
376 * Move all frames on our prev-in-flow's and our own ExcessOverflowContainers
377 * lists to our OverflowContainers list. If there are frames on multiple
378 * lists they are merged using aMergeFunc.
379 * @return a pointer to our OverflowContainers list, if any
380 */
381 nsFrameList* DrainExcessOverflowContainersList(
382 ChildFrameMerger aMergeFunc = DefaultChildFrameMerge);
383
384 /**
385 * Removes aChild without destroying it and without requesting reflow.
386 * Continuations are not affected. Checks the principal and overflow lists,
387 * and also the [excess] overflow containers lists if the frame bit
388 * NS_FRAME_IS_OVERFLOW_CONTAINER is set. It does not check any other lists.
389 * Returns NS_ERROR_UNEXPECTED if aChild wasn't found on any of the lists
390 * mentioned above.
391 */
392 virtual nsresult StealFrame(nsIFrame* aChild);
393
394 /**
395 * Removes the next-siblings of aChild without destroying them and without
396 * requesting reflow. Checks the principal and overflow lists (not
397 * overflow containers / excess overflow containers). Does not check any
398 * other auxiliary lists.
399 * @param aChild a child frame or nullptr
400 * @return If aChild is non-null, the next-siblings of aChild, if any.
401 * If aChild is null, all child frames on the principal list, if any.
402 */
403 nsFrameList StealFramesAfter(nsIFrame* aChild);
404
405 /**
406 * Add overflow containers to the display list
407 */
408 void DisplayOverflowContainers(nsDisplayListBuilder* aBuilder,
409 const nsDisplayListSet& aLists);
410
411 /**
412 * Builds display lists for the children. The background
413 * of each child is placed in the Content() list (suitable for inline
414 * children and other elements that behave like inlines,
415 * but not for in-flow block children of blocks). DOES NOT
416 * paint the background/borders/outline of this frame. This should
417 * probably be avoided and eventually removed. It's currently here
418 * to emulate what nsContainerFrame::Paint did.
419 */
420 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
421 const nsDisplayListSet& aLists) override;
422
PlaceFrameView(nsIFrame * aFrame)423 static void PlaceFrameView(nsIFrame* aFrame) {
424 if (aFrame->HasView())
425 nsContainerFrame::PositionFrameView(aFrame);
426 else
427 nsContainerFrame::PositionChildViews(aFrame);
428 }
429
430 /**
431 * Returns a CSS Box Alignment constant which the caller can use to align
432 * the absolutely-positioned child (whose ReflowInput is aChildRI) within
433 * a CSS Box Alignment area associated with this container.
434 *
435 * The lower 8 bits of the returned value are guaranteed to form a valid
436 * argument for CSSAlignUtils::AlignJustifySelf(). (The upper 8 bits may
437 * encode an <overflow-position>.)
438 *
439 * NOTE: This default nsContainerFrame implementation is a stub, and isn't
440 * meant to be called. Subclasses must provide their own implementations, if
441 * they use CSS Box Alignment to determine the static position of their
442 * absolutely-positioned children. (Though: if subclasses share enough code,
443 * maybe this nsContainerFrame impl should include some shared code.)
444 *
445 * @param aChildRI A ReflowInput for the positioned child frame that's being
446 * aligned.
447 * @param aLogicalAxis The axis (of this container frame) in which the caller
448 * would like to align the child frame.
449 */
450 virtual mozilla::StyleAlignFlags CSSAlignmentForAbsPosChild(
451 const ReflowInput& aChildRI, mozilla::LogicalAxis aLogicalAxis) const;
452
453 #define NS_DECLARE_FRAME_PROPERTY_FRAMELIST(prop) \
454 NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, nsFrameList)
455
456 typedef PropertyDescriptor<nsFrameList> FrameListPropertyDescriptor;
457
458 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowProperty)
NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowContainersProperty)459 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowContainersProperty)
460 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(ExcessOverflowContainersProperty)
461 NS_DECLARE_FRAME_PROPERTY_FRAMELIST(BackdropProperty)
462
463 // Only really used on nsBlockFrame instances, but the caller thinks it could
464 // have arbitrary nsContainerFrames.
465 NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(FirstLetterProperty, nsIFrame)
466
467 void SetHasFirstLetterChild() { mHasFirstLetterChild = true; }
468
ClearHasFirstLetterChild()469 void ClearHasFirstLetterChild() { mHasFirstLetterChild = false; }
470
471 #ifdef DEBUG
472 // Use this to suppress the CRAZY_SIZE assertions.
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize,bool)473 NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool)
474 bool IsCrazySizeAssertSuppressed() const {
475 return GetProperty(DebugReflowingWithInfiniteISize());
476 }
477 #endif
478
479 // Incorporate the child overflow areas into aOverflowAreas.
480 // If the child does not have a overflow, use the child area.
481 void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
482 nsIFrame* aChildFrame);
483
484 protected:
nsContainerFrame(ComputedStyle * aStyle,nsPresContext * aPresContext,ClassID aID)485 nsContainerFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
486 ClassID aID)
487 : nsSplittableFrame(aStyle, aPresContext, aID) {}
488
489 ~nsContainerFrame();
490
491 /**
492 * Helper for DestroyFrom. DestroyAbsoluteFrames is called before
493 * destroying frames on lists that can contain placeholders.
494 * Derived classes must do that too, if they destroy such frame lists.
495 * See nsBlockFrame::DestroyFrom for an example.
496 */
497 void DestroyAbsoluteFrames(nsIFrame* aDestructRoot,
498 PostDestroyData& aPostDestroyData);
499
500 /**
501 * Helper for StealFrame. Returns true if aChild was removed from its list.
502 */
503 bool MaybeStealOverflowContainerFrame(nsIFrame* aChild);
504
505 /**
506 * Builds a display list for non-block children that behave like
507 * inlines. This puts the background of each child into the
508 * Content() list (suitable for inline children but not for
509 * in-flow block children of blocks).
510 * @param aForcePseudoStack forces each child into a pseudo-stacking-context
511 * so its background and all other display items (except for positioned
512 * display items) go into the Content() list.
513 */
514 void BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder,
515 const nsDisplayListSet& aLists,
516 uint32_t aFlags = 0);
517
518 /**
519 * A version of BuildDisplayList that use DISPLAY_CHILD_INLINE.
520 * Intended as a convenience for derived classes.
521 */
BuildDisplayListForInline(nsDisplayListBuilder * aBuilder,const nsDisplayListSet & aLists)522 void BuildDisplayListForInline(nsDisplayListBuilder* aBuilder,
523 const nsDisplayListSet& aLists) {
524 DisplayBorderBackgroundOutline(aBuilder, aLists);
525 BuildDisplayListForNonBlockChildren(aBuilder, aLists, DISPLAY_CHILD_INLINE);
526 }
527
528 // ==========================================================================
529 /* Overflow Frames are frames that did not fit and must be pulled by
530 * our next-in-flow during its reflow. (The same concept for overflow
531 * containers is called "excess frames". We should probably make the
532 * names match.)
533 */
534
535 /**
536 * Get the frames on the overflow list. Can return null if there are no
537 * overflow frames. The caller does NOT take ownership of the list; it's
538 * still owned by this frame. A non-null return value indicates that the
539 * list is nonempty.
540 */
541 inline nsFrameList* GetOverflowFrames() const;
542
543 /**
544 * As GetOverflowFrames, but removes the overflow frames property. The
545 * caller is responsible for deleting nsFrameList and either passing
546 * ownership of the frames to someone else or destroying the frames.
547 * A non-null return value indicates that the list is nonempty. The
548 * recommended way to use this function it to assign its return value
549 * into an AutoFrameListPtr.
550 */
551 inline nsFrameList* StealOverflowFrames();
552
553 /**
554 * Set the overflow list. aOverflowFrames must not be an empty list.
555 */
556 void SetOverflowFrames(const nsFrameList& aOverflowFrames);
557
558 /**
559 * Destroy the overflow list, which must be empty.
560 */
561 inline void DestroyOverflowList();
562
563 /**
564 * Moves any frames on both the prev-in-flow's overflow list and the
565 * receiver's overflow to the receiver's child list.
566 *
567 * Resets the overlist pointers to nullptr, and updates the receiver's child
568 * count and content mapping.
569 *
570 * @return true if any frames were moved and false otherwise
571 */
572 bool MoveOverflowToChildList();
573
574 /**
575 * Merge a sorted frame list into our overflow list. aList becomes empty after
576 * this call.
577 */
578 void MergeSortedOverflow(nsFrameList& aList);
579
580 /**
581 * Merge a sorted frame list into our excess overflow containers list. aList
582 * becomes empty after this call.
583 */
584 void MergeSortedExcessOverflowContainers(nsFrameList& aList);
585
586 /**
587 * Moves all frames from aSrc into aDest such that the resulting aDest
588 * is still sorted in document content order and continuation order. aSrc
589 * becomes empty after this call.
590 *
591 * Precondition: both |aSrc| and |aDest| must be sorted to begin with.
592 * @param aCommonAncestor a hint for nsLayoutUtils::CompareTreePosition
593 */
594 static void MergeSortedFrameLists(nsFrameList& aDest, nsFrameList& aSrc,
595 nsIContent* aCommonAncestor);
596
597 /**
598 * This is intended to be used as a ChildFrameMerger argument for
599 * ReflowOverflowContainerChildren().
600 */
MergeSortedFrameListsFor(nsFrameList & aDest,nsFrameList & aSrc,nsContainerFrame * aParent)601 static inline void MergeSortedFrameListsFor(nsFrameList& aDest,
602 nsFrameList& aSrc,
603 nsContainerFrame* aParent) {
604 MergeSortedFrameLists(aDest, aSrc, aParent->GetContent());
605 }
606
607 /**
608 * Basically same as MoveOverflowToChildList, except that this is for
609 * handling inline children where children of prev-in-flow can be
610 * pushed to overflow list even if a next-in-flow exists.
611 *
612 * @param aLineContainer the line container of the current frame.
613 *
614 * @return true if any frames were moved and false otherwise
615 */
616 bool MoveInlineOverflowToChildList(nsIFrame* aLineContainer);
617
618 /**
619 * Push aFromChild and its next siblings to the overflow list.
620 *
621 * @param aFromChild the first child frame to push. It is disconnected
622 * from aPrevSibling
623 * @param aPrevSibling aFrameChild's previous sibling. Must not be null.
624 * It's an error to push a parent's first child frame.
625 */
626 void PushChildrenToOverflow(nsIFrame* aFromChild, nsIFrame* aPrevSibling);
627
628 /**
629 * Same as above, except that this pushes frames to the next-in-flow
630 * frame and changes the geometric parent of the pushed frames when
631 * there is a next-in-flow frame.
632 *
633 * Updates the next-in-flow's child count. Does <b>not</b> update the
634 * pusher's child count.
635 */
636 void PushChildren(nsIFrame* aFromChild, nsIFrame* aPrevSibling);
637
638 /**
639 * Iterate our children in our principal child list in the normal document
640 * order, and append them (or their next-in-flows) to either our overflow list
641 * or excess overflow container list according to their presence in
642 * aPushedItems, aIncompleteItems, or aOverflowIncompleteItems.
643 *
644 * Note: This method is only intended for Grid / Flex containers.
645 * aPushedItems, aIncompleteItems, and aOverflowIncompleteItems are expected
646 * to contain only Grid / Flex items. That is, they should contain only
647 * in-flow children.
648 *
649 * @return true if any items are moved; false otherwise.
650 */
651 using FrameHashtable = nsTHashtable<nsPtrHashKey<nsIFrame>>;
652 bool PushIncompleteChildren(const FrameHashtable& aPushedItems,
653 const FrameHashtable& aIncompleteItems,
654 const FrameHashtable& aOverflowIncompleteItems);
655
656 /**
657 * Prepare our child lists so that they are ready to reflow by the following
658 * operations:
659 *
660 * - Merge overflow list from our prev-in-flow into our principal child list.
661 * - Merge our own overflow list into our principal child list,
662 * - Push any child's next-in-flows in our principal child list to our
663 * overflow list.
664 * - Pull up any first-in-flow child we might have pushed from our
665 * next-in-flows.
666 */
667 void NormalizeChildLists();
668
669 /**
670 * Helper to implement AppendFrames / InsertFrames for flex / grid
671 * containers.
672 */
673 void NoteNewChildren(ChildListID aListID, const nsFrameList& aFrameList);
674
675 /**
676 * Helper to implement DrainSelfOverflowList() for flex / grid containers.
677 */
678 bool DrainAndMergeSelfOverflowList();
679
680 /**
681 * Reparent floats whose placeholders are inline descendants of aFrame from
682 * whatever block they're currently parented by to aOurBlock.
683 * @param aReparentSiblings if this is true, we follow aFrame's
684 * GetNextSibling chain reparenting them all
685 */
686 static void ReparentFloatsForInlineChild(nsIFrame* aOurBlock,
687 nsIFrame* aFrame,
688 bool aReparentSiblings);
689
690 // ==========================================================================
691 /*
692 * Convenience methods for traversing continuations
693 */
694
695 struct ContinuationTraversingState {
696 nsContainerFrame* mNextInFlow;
ContinuationTraversingStateContinuationTraversingState697 explicit ContinuationTraversingState(nsContainerFrame* aFrame)
698 : mNextInFlow(static_cast<nsContainerFrame*>(aFrame->GetNextInFlow())) {
699 }
700 };
701
702 /**
703 * Find the first frame that is a child of this frame's next-in-flows,
704 * considering both their principal child lists and overflow lists.
705 */
706 nsIFrame* GetNextInFlowChild(ContinuationTraversingState& aState,
707 bool* aIsInOverflow = nullptr);
708
709 /**
710 * Remove the result of GetNextInFlowChild from its current parent and
711 * append it to this frame's principal child list.
712 */
713 nsIFrame* PullNextInFlowChild(ContinuationTraversingState& aState);
714
715 // ==========================================================================
716 /*
717 * Convenience methods for nsFrameLists stored in the
718 * PresContext's proptable
719 */
720
721 /**
722 * Get the PresContext-stored nsFrameList named aPropID for this frame.
723 * May return null.
724 */
725 nsFrameList* GetPropTableFrames(FrameListPropertyDescriptor aProperty) const;
726
727 /**
728 * Remove and return the PresContext-stored nsFrameList named aPropID for
729 * this frame. May return null.
730 */
731 nsFrameList* RemovePropTableFrames(FrameListPropertyDescriptor aProperty);
732
733 /**
734 * Set the PresContext-stored nsFrameList named aPropID for this frame
735 * to the given aFrameList, which must not be null.
736 */
737 void SetPropTableFrames(nsFrameList* aFrameList,
738 FrameListPropertyDescriptor aProperty);
739
740 /**
741 * Safely destroy the frames on the nsFrameList stored on aProp for this
742 * frame then remove the property and delete the frame list.
743 * Nothing happens if the property doesn't exist.
744 */
745 void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
746 PostDestroyData& aPostDestroyData,
747 mozilla::PresShell* aPresShell,
748 FrameListPropertyDescriptor aProp);
749
750 // ==========================================================================
751
752 // Helper used by Progress and Meter frames. Returns true if the bar should
753 // be rendered vertically, based on writing-mode and -moz-orient properties.
754 bool ResolvedOrientationIsVertical();
755
756 /**
757 * Calculate the used values for 'width' and 'height' for a replaced element.
758 * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
759 */
760 mozilla::LogicalSize ComputeSizeWithIntrinsicDimensions(
761 gfxContext* aRenderingContext, mozilla::WritingMode aWM,
762 const mozilla::IntrinsicSize& aIntrinsicSize,
763 const mozilla::AspectRatio& aIntrinsicRatio,
764 const mozilla::LogicalSize& aCBSize, const mozilla::LogicalSize& aMargin,
765 const mozilla::LogicalSize& aBorder, const mozilla::LogicalSize& aPadding,
766 ComputeSizeFlags aFlags);
767
768 // Compute tight bounds assuming this frame honours its border, background
769 // and outline, its children's tight bounds, and nothing else.
770 nsRect ComputeSimpleTightBounds(mozilla::gfx::DrawTarget* aDrawTarget) const;
771
772 /*
773 * If this frame is dirty, marks all absolutely-positioned children of this
774 * frame dirty. If this frame isn't dirty, or if there are no
775 * absolutely-positioned children, does nothing.
776 *
777 * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
778 * reflow this frame's absolutely-positioned children after the dirty bit on
779 * this frame has already been cleared, which prevents ReflowInput from
780 * propagating the dirty bit normally. This situation generally only arises
781 * when a multipass layout algorithm is used.
782 */
783 void PushDirtyBitToAbsoluteFrames();
784
785 // Helper function that tests if the frame tree is too deep; if it is
786 // it marks the frame as "unflowable", zeroes out the metrics, sets
787 // the reflow status, and returns true. Otherwise, the frame is
788 // unmarked "unflowable" and the metrics and reflow status are not
789 // touched and false is returned.
790 bool IsFrameTreeTooDeep(const ReflowInput& aReflowInput,
791 ReflowOutput& aMetrics, nsReflowStatus& aStatus);
792
793 /**
794 * @return true if we should avoid a page/column break in this frame.
795 */
796 bool ShouldAvoidBreakInside(const ReflowInput& aReflowInput) const;
797
798 /**
799 * To be called by |BuildDisplayLists| of this class or derived classes to add
800 * a translucent overlay if this frame's content is selected.
801 * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
802 * which kind of content this is for
803 */
804 void DisplaySelectionOverlay(
805 nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
806 uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
807
808 // ==========================================================================
809
810 #ifdef DEBUG
811 // A helper for flex / grid container to sanity check child lists before
812 // reflow. Intended to be called after calling NormalizeChildLists().
813 void SanityCheckChildListsBeforeReflow() const;
814
815 // A helper to set mDidPushItemsBitMayLie if needed. Intended to be called
816 // only in flex / grid container's RemoveFrame.
817 void SetDidPushItemsBitIfNeeded(ChildListID aListID, nsIFrame* aOldFrame);
818
819 // A flag for flex / grid containers. If true, NS_STATE_GRID_DID_PUSH_ITEMS or
820 // NS_STATE_FLEX_DID_PUSH_ITEMS may be set even though all pushed frames may
821 // have been removed. This is used to suppress an assertion in case
822 // RemoveFrame removed all associated child frames.
823 bool mDidPushItemsBitMayLie{false};
824 #endif
825
826 nsFrameList mFrames;
827 };
828
829 // ==========================================================================
830 /* The out-of-flow-related code below is for a hacky way of splitting
831 * absolutely-positioned frames. Basically what we do is split the frame
832 * in nsAbsoluteContainingBlock and pretend the continuation is an overflow
833 * container. This isn't an ideal solution, but it lets us print the content
834 * at least. See bug 154892.
835 */
836
837 #define IS_TRUE_OVERFLOW_CONTAINER(frame) \
838 ((frame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) && \
839 !((frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) && \
840 frame->IsAbsolutelyPositioned()))
841 // XXXfr This check isn't quite correct, because it doesn't handle cases
842 // where the out-of-flow has overflow.. but that's rare.
843 // We'll need to revisit the way abspos continuations are handled later
844 // for various reasons, this detail is one of them. See bug 154892
845
846 /**
847 * Helper class for tracking overflow container continuations during reflow.
848 *
849 * A frame is related to two sets of overflow containers: those that /are/
850 * its own children, and those that are /continuations/ of its children.
851 * This tracker walks through those continuations (the frame's NIF's children)
852 * and their prev-in-flows (a subset of the frame's normal and overflow
853 * container children) in parallel. It allows the reflower to synchronously
854 * walk its overflow continuations while it loops through and reflows its
855 * children. This makes it possible to insert new continuations at the correct
856 * place in the overflow containers list.
857 *
858 * The reflower is expected to loop through its children in the same order it
859 * looped through them the last time (if there was a last time).
860 * For each child, the reflower should either
861 * - call Skip for the child if was not reflowed in this pass
862 * - call Insert for the overflow continuation if the child was reflowed
863 * but has incomplete overflow
864 * - call Finished for the child if it was reflowed in this pass but
865 * is either complete or has a normal next-in-flow. This call can
866 * be skipped if the child did not previously have an overflow
867 * continuation.
868 */
869 class nsOverflowContinuationTracker {
870 public:
871 /**
872 * Initializes an nsOverflowContinuationTracker to help track overflow
873 * continuations of aFrame's children. Typically invoked on 'this'.
874 *
875 * aWalkOOFFrames determines whether the walker skips out-of-flow frames
876 * or skips non-out-of-flow frames.
877 *
878 * Don't set aSkipOverflowContainerChildren to false unless you plan
879 * to walk your own overflow container children. (Usually they are handled
880 * by calling ReflowOverflowContainerChildren.) aWalkOOFFrames is ignored
881 * if aSkipOverflowContainerChildren is false.
882 */
883 nsOverflowContinuationTracker(nsContainerFrame* aFrame, bool aWalkOOFFrames,
884 bool aSkipOverflowContainerChildren = true);
885 /**
886 * This function adds an overflow continuation to our running list and
887 * sets its NS_FRAME_IS_OVERFLOW_CONTAINER flag.
888 *
889 * aReflowStatus should preferably be specific to the recently-reflowed
890 * child and not influenced by any of its siblings' statuses. This
891 * function sets the NS_FRAME_IS_DIRTY bit on aOverflowCont if it needs
892 * to be reflowed. (Its need for reflow depends on changes to its
893 * prev-in-flow, not to its parent--for whom it is invisible, reflow-wise.)
894 *
895 * The caller MUST disconnect the frame from its parent's child list
896 * if it was not previously an NS_FRAME_IS_OVERFLOW_CONTAINER (because
897 * StealFrame is much more inefficient than disconnecting in place
898 * during Reflow, which the caller is able to do but we are not).
899 *
900 * The caller MUST NOT disconnect the frame from its parent's
901 * child list if it is already an NS_FRAME_IS_OVERFLOW_CONTAINER.
902 * (In this case we will disconnect and reconnect it ourselves.)
903 */
904 nsresult Insert(nsIFrame* aOverflowCont, nsReflowStatus& aReflowStatus);
905 /**
906 * Begin/EndFinish() must be called for each child that is reflowed
907 * but no longer has an overflow continuation. (It may be called for
908 * other children, but in that case has no effect.) It increments our
909 * walker and makes sure we drop any dangling pointers to its
910 * next-in-flow. This function MUST be called before stealing or
911 * deleting aChild's next-in-flow.
912 * The AutoFinish helper object does that for you. Use it like so:
913 * if (kidNextInFlow) {
914 * nsOverflowContinuationTracker::AutoFinish fini(tracker, kid);
915 * ... DeleteNextInFlowChild/StealFrame(kidNextInFlow) here ...
916 * }
917 */
918 class MOZ_RAII AutoFinish {
919 public:
AutoFinish(nsOverflowContinuationTracker * aTracker,nsIFrame * aChild)920 AutoFinish(nsOverflowContinuationTracker* aTracker, nsIFrame* aChild)
921 : mTracker(aTracker), mChild(aChild) {
922 if (mTracker) mTracker->BeginFinish(mChild);
923 }
~AutoFinish()924 ~AutoFinish() {
925 if (mTracker) mTracker->EndFinish(mChild);
926 }
927
928 private:
929 nsOverflowContinuationTracker* mTracker;
930 nsIFrame* mChild;
931 };
932
933 /**
934 * This function should be called for each child that isn't reflowed.
935 * It increments our walker and sets the mOverflowIncomplete
936 * reflow flag if it encounters an overflow continuation so that our
937 * next-in-flow doesn't get prematurely deleted. It MUST be called on
938 * each unreflowed child that has an overflow container continuation;
939 * it MAY be called on other children, but it isn't necessary (doesn't
940 * do anything).
941 */
Skip(nsIFrame * aChild,nsReflowStatus & aReflowStatus)942 void Skip(nsIFrame* aChild, nsReflowStatus& aReflowStatus) {
943 MOZ_ASSERT(aChild, "null ptr");
944 if (aChild == mSentry) {
945 StepForward();
946 if (aReflowStatus.IsComplete()) {
947 aReflowStatus.SetOverflowIncomplete();
948 }
949 }
950 }
951
952 private:
953 /**
954 * @see class AutoFinish
955 */
956 void BeginFinish(nsIFrame* aChild);
957 void EndFinish(nsIFrame* aChild);
958
959 void SetupOverflowContList();
960 void SetUpListWalker();
961 void StepForward();
962
963 /* We hold a pointer to either the next-in-flow's overflow containers list
964 or, if that doesn't exist, our frame's excess overflow containers list.
965 We need to make sure that we drop that pointer if the list becomes
966 empty and is deleted elsewhere. */
967 nsFrameList* mOverflowContList;
968 /* We hold a pointer to the most recently-reflowed child that has an
969 overflow container next-in-flow. We do this because it's a known
970 good point; this pointer won't be deleted on us. We can use it to
971 recover our place in the list. */
972 nsIFrame* mPrevOverflowCont;
973 /* This is a pointer to the next overflow container's prev-in-flow, which
974 is (or should be) a child of our frame. When we hit this, we will need
975 to increment this walker to the next overflow container. */
976 nsIFrame* mSentry;
977 /* Parent of all frames in mOverflowContList. If our mOverflowContList
978 is an excessOverflowContainersProperty, or null, then this is our frame
979 (the frame that was passed in to our constructor). Otherwise this is
980 that frame's next-in-flow, and our mOverflowContList is mParent's
981 overflowContainersProperty */
982 nsContainerFrame* mParent;
983 /* Tells SetUpListWalker whether or not to walk us past any continuations
984 of overflow containers. aWalkOOFFrames is ignored when this is false. */
985 bool mSkipOverflowContainerChildren;
986 /* Tells us whether to pay attention to OOF frames or non-OOF frames */
987 bool mWalkOOFFrames;
988 };
989
GetOverflowFrames()990 inline nsFrameList* nsContainerFrame::GetOverflowFrames() const {
991 nsFrameList* list = GetProperty(OverflowProperty());
992 NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
993 return list;
994 }
995
StealOverflowFrames()996 inline nsFrameList* nsContainerFrame::StealOverflowFrames() {
997 nsFrameList* list = TakeProperty(OverflowProperty());
998 NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
999 return list;
1000 }
1001
DestroyOverflowList()1002 inline void nsContainerFrame::DestroyOverflowList() {
1003 nsFrameList* list = RemovePropTableFrames(OverflowProperty());
1004 MOZ_ASSERT(list && list->IsEmpty());
1005 list->Delete(PresShell());
1006 }
1007
1008 // Start Display Reflow Debugging
1009 #ifdef DEBUG
1010
1011 struct DR_cookie {
1012 DR_cookie(nsPresContext* aPresContext, nsIFrame* aFrame,
1013 const mozilla::ReflowInput& aReflowInput,
1014 mozilla::ReflowOutput& aMetrics, nsReflowStatus& aStatus);
1015 ~DR_cookie();
1016 void Change() const;
1017
1018 nsPresContext* mPresContext;
1019 nsIFrame* mFrame;
1020 const mozilla::ReflowInput& mReflowInput;
1021 mozilla::ReflowOutput& mMetrics;
1022 nsReflowStatus& mStatus;
1023 void* mValue;
1024 };
1025
1026 struct DR_layout_cookie {
1027 explicit DR_layout_cookie(nsIFrame* aFrame);
1028 ~DR_layout_cookie();
1029
1030 nsIFrame* mFrame;
1031 void* mValue;
1032 };
1033
1034 struct DR_intrinsic_inline_size_cookie {
1035 DR_intrinsic_inline_size_cookie(nsIFrame* aFrame, const char* aType,
1036 nscoord& aResult);
1037 ~DR_intrinsic_inline_size_cookie();
1038
1039 nsIFrame* mFrame;
1040 const char* mType;
1041 nscoord& mResult;
1042 void* mValue;
1043 };
1044
1045 struct DR_intrinsic_size_cookie {
1046 DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
1047 nsSize& aResult);
1048 ~DR_intrinsic_size_cookie();
1049
1050 nsIFrame* mFrame;
1051 const char* mType;
1052 nsSize& mResult;
1053 void* mValue;
1054 };
1055
1056 struct DR_init_constraints_cookie {
1057 DR_init_constraints_cookie(nsIFrame* aFrame, mozilla::ReflowInput* aState,
1058 nscoord aCBWidth, nscoord aCBHeight,
1059 const nsMargin* aMargin, const nsMargin* aPadding);
1060 ~DR_init_constraints_cookie();
1061
1062 nsIFrame* mFrame;
1063 mozilla::ReflowInput* mState;
1064 void* mValue;
1065 };
1066
1067 struct DR_init_offsets_cookie {
1068 DR_init_offsets_cookie(nsIFrame* aFrame,
1069 mozilla::SizeComputationInput* aState,
1070 nscoord aPercentBasis,
1071 mozilla::WritingMode aCBWritingMode,
1072 const nsMargin* aMargin, const nsMargin* aPadding);
1073 ~DR_init_offsets_cookie();
1074
1075 nsIFrame* mFrame;
1076 mozilla::SizeComputationInput* mState;
1077 void* mValue;
1078 };
1079
1080 struct DR_init_type_cookie {
1081 DR_init_type_cookie(nsIFrame* aFrame, mozilla::ReflowInput* aState);
1082 ~DR_init_type_cookie();
1083
1084 nsIFrame* mFrame;
1085 mozilla::ReflowInput* mState;
1086 void* mValue;
1087 };
1088
1089 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1090 dr_rf_metrics, dr_rf_status) \
1091 DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, \
1092 dr_rf_status);
1093 # define DISPLAY_REFLOW_CHANGE() dr_cookie.Change();
1094 # define DISPLAY_LAYOUT(dr_frame) DR_layout_cookie dr_cookie(dr_frame);
1095 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1096 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1097 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1098 DR_intrinsic_inline_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1099 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
1100 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
1101 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
1102 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
1103 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
1104 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
1105 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1106 dr_pad) \
1107 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
1108 dr_bdr, dr_pad)
1109 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1110 dr_pad) \
1111 DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_pb, dr_cbwm, \
1112 dr_bdr, dr_pad)
1113 # define DISPLAY_INIT_TYPE(dr_frame, dr_result) \
1114 DR_init_type_cookie dr_cookie(dr_frame, dr_result)
1115
1116 #else
1117
1118 # define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, \
1119 dr_rf_metrics, dr_rf_status)
1120 # define DISPLAY_REFLOW_CHANGE()
1121 # define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
1122 # define DISPLAY_MIN_INLINE_SIZE(dr_frame, dr_result) \
1123 PR_BEGIN_MACRO PR_END_MACRO
1124 # define DISPLAY_PREF_INLINE_SIZE(dr_frame, dr_result) \
1125 PR_BEGIN_MACRO PR_END_MACRO
1126 # define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1127 # define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1128 # define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1129 # define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, dr_bdr, \
1130 dr_pad) \
1131 PR_BEGIN_MACRO PR_END_MACRO
1132 # define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr, \
1133 dr_pad) \
1134 PR_BEGIN_MACRO PR_END_MACRO
1135 # define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
1136
1137 #endif
1138 // End Display Reflow Debugging
1139
1140 #endif /* nsContainerFrame_h___ */
1141