tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsContainerFrame.h (48236B)


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