layout/generic/nsBlockFrame.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsBlockFrame.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,987 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +// vim:cindent:ts=2:et:sw=2:
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/*
    1.11 + * rendering object for CSS display:block, inline-block, and list-item
    1.12 + * boxes, also used for various anonymous boxes
    1.13 + */
    1.14 +
    1.15 +#ifndef nsBlockFrame_h___
    1.16 +#define nsBlockFrame_h___
    1.17 +
    1.18 +#include "nsContainerFrame.h"
    1.19 +#include "nsHTMLParts.h"
    1.20 +#include "nsLineBox.h"
    1.21 +#include "nsCSSPseudoElements.h"
    1.22 +#include "nsStyleSet.h"
    1.23 +#include "nsFloatManager.h"
    1.24 +
    1.25 +enum LineReflowStatus {
    1.26 +  // The line was completely reflowed and fit in available width, and we should
    1.27 +  // try to pull up content from the next line if possible.
    1.28 +  LINE_REFLOW_OK,
    1.29 +  // The line was completely reflowed and fit in available width, but we should
    1.30 +  // not try to pull up content from the next line.
    1.31 +  LINE_REFLOW_STOP,
    1.32 +  // We need to reflow the line again at its current vertical position. The
    1.33 +  // new reflow should not try to pull up any frames from the next line.
    1.34 +  LINE_REFLOW_REDO_NO_PULL,
    1.35 +  // We need to reflow the line again using the floats from its height
    1.36 +  // this reflow, since its height made it hit floats that were not
    1.37 +  // adjacent to its top.
    1.38 +  LINE_REFLOW_REDO_MORE_FLOATS,
    1.39 +  // We need to reflow the line again at a lower vertical postion where there
    1.40 +  // may be more horizontal space due to different float configuration.
    1.41 +  LINE_REFLOW_REDO_NEXT_BAND,
    1.42 +  // The line did not fit in the available vertical space. Try pushing it to
    1.43 +  // the next page or column if it's not the first line on the current page/column.
    1.44 +  LINE_REFLOW_TRUNCATED
    1.45 +};
    1.46 +
    1.47 +class nsBlockReflowState;
    1.48 +class nsBlockInFlowLineIterator;
    1.49 +class nsBulletFrame;
    1.50 +class nsFirstLineFrame;
    1.51 +
    1.52 +/**
    1.53 + * Some invariants:
    1.54 + * -- The overflow out-of-flows list contains the out-of-
    1.55 + * flow frames whose placeholders are in the overflow list.
    1.56 + * -- A given piece of content has at most one placeholder
    1.57 + * frame in a block's normal child list.
    1.58 + * -- While a block is being reflowed, and from then until
    1.59 + * its next-in-flow is reflowed it may have a
    1.60 + * PushedFloatProperty frame property that points to
    1.61 + * an nsFrameList. This list contains continuations for
    1.62 + * floats whose prev-in-flow is in the block's regular float
    1.63 + * list and first-in-flows of floats that did not fit, but
    1.64 + * whose placeholders are in the block or one of its
    1.65 + * prev-in-flows.
    1.66 + * -- In all these frame lists, if there are two frames for
    1.67 + * the same content appearing in the list, then the frames
    1.68 + * appear with the prev-in-flow before the next-in-flow.
    1.69 + * -- While reflowing a block, its overflow line list
    1.70 + * will usually be empty but in some cases will have lines
    1.71 + * (while we reflow the block at its shrink-wrap width).
    1.72 + * In this case any new overflowing content must be
    1.73 + * prepended to the overflow lines.
    1.74 + */
    1.75 +
    1.76 +typedef nsContainerFrame nsBlockFrameSuper;
    1.77 +
    1.78 +/*
    1.79 + * Base class for block and inline frames.
    1.80 + * The block frame has an additional child list, kAbsoluteList, which
    1.81 + * contains the absolutely positioned frames.
    1.82 + */ 
    1.83 +class nsBlockFrame : public nsBlockFrameSuper
    1.84 +{
    1.85 +public:
    1.86 +  NS_DECL_QUERYFRAME_TARGET(nsBlockFrame)
    1.87 +  NS_DECL_FRAMEARENA_HELPERS
    1.88 +
    1.89 +  typedef nsLineList::iterator                  line_iterator;
    1.90 +  typedef nsLineList::const_iterator            const_line_iterator;
    1.91 +  typedef nsLineList::reverse_iterator          reverse_line_iterator;
    1.92 +  typedef nsLineList::const_reverse_iterator    const_reverse_line_iterator;
    1.93 +
    1.94 +  line_iterator begin_lines() { return mLines.begin(); }
    1.95 +  line_iterator end_lines() { return mLines.end(); }
    1.96 +  const_line_iterator begin_lines() const { return mLines.begin(); }
    1.97 +  const_line_iterator end_lines() const { return mLines.end(); }
    1.98 +  reverse_line_iterator rbegin_lines() { return mLines.rbegin(); }
    1.99 +  reverse_line_iterator rend_lines() { return mLines.rend(); }
   1.100 +  const_reverse_line_iterator rbegin_lines() const { return mLines.rbegin(); }
   1.101 +  const_reverse_line_iterator rend_lines() const { return mLines.rend(); }
   1.102 +  line_iterator line(nsLineBox* aList) { return mLines.begin(aList); }
   1.103 +  reverse_line_iterator rline(nsLineBox* aList) { return mLines.rbegin(aList); }
   1.104 +
   1.105 +  friend nsIFrame* NS_NewBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
   1.106 +
   1.107 +  // nsQueryFrame
   1.108 +  NS_DECL_QUERYFRAME
   1.109 +
   1.110 +  // nsIFrame
   1.111 +  virtual void Init(nsIContent*      aContent,
   1.112 +                    nsIFrame*        aParent,
   1.113 +                    nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
   1.114 +  virtual nsresult SetInitialChildList(ChildListID     aListID,
   1.115 +                                       nsFrameList&    aChildList) MOZ_OVERRIDE;
   1.116 +  virtual nsresult  AppendFrames(ChildListID     aListID,
   1.117 +                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
   1.118 +  virtual nsresult  InsertFrames(ChildListID     aListID,
   1.119 +                                 nsIFrame*       aPrevFrame,
   1.120 +                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
   1.121 +  virtual nsresult  RemoveFrame(ChildListID     aListID,
   1.122 +                                nsIFrame*       aOldFrame) MOZ_OVERRIDE;
   1.123 +  virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
   1.124 +  virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
   1.125 +  virtual nscoord GetBaseline() const MOZ_OVERRIDE;
   1.126 +  virtual nscoord GetCaretBaseline() const MOZ_OVERRIDE;
   1.127 +  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   1.128 +  virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
   1.129 +  virtual bool IsFloatContainingBlock() const MOZ_OVERRIDE;
   1.130 +  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   1.131 +                                const nsRect&           aDirtyRect,
   1.132 +                                const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   1.133 +  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   1.134 +  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   1.135 +  {
   1.136 +    return nsContainerFrame::IsFrameOfType(aFlags &
   1.137 +             ~(nsIFrame::eCanContainOverflowContainers |
   1.138 +               nsIFrame::eBlockFrame));
   1.139 +  }
   1.140 +
   1.141 +  virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   1.142 +  virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
   1.143 +
   1.144 +#ifdef DEBUG_FRAME_DUMP
   1.145 +  void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const MOZ_OVERRIDE;
   1.146 +  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   1.147 +#endif
   1.148 +
   1.149 +#ifdef DEBUG
   1.150 +  virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE;
   1.151 +#endif
   1.152 +
   1.153 +#ifdef ACCESSIBILITY
   1.154 +  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
   1.155 +#endif
   1.156 +
   1.157 +  // line cursor methods to speed up searching for the line(s)
   1.158 +  // containing a point. The basic idea is that we set the cursor
   1.159 +  // property if the lines' overflowArea.VisualOverflow().ys and
   1.160 +  // overflowArea.VisualOverflow().yMosts are non-decreasing
   1.161 +  // (considering only non-empty overflowArea.VisualOverflow()s; empty
   1.162 +  // overflowArea.VisualOverflow()s never participate in event handling
   1.163 +  // or painting), and the block has sufficient number of lines. The
   1.164 +  // cursor property points to a "recently used" line. If we get a
   1.165 +  // series of requests that work on lines
   1.166 +  // "near" the cursor, then we can find those nearby lines quickly by
   1.167 +  // starting our search at the cursor.
   1.168 +
   1.169 +  // Clear out line cursor because we're disturbing the lines (i.e., Reflow)
   1.170 +  void ClearLineCursor();
   1.171 +  // Get the first line that might contain y-coord 'y', or nullptr if you must search
   1.172 +  // all lines. If nonnull is returned then we guarantee that the lines'
   1.173 +  // combinedArea.ys and combinedArea.yMosts are non-decreasing.
   1.174 +  // The actual line returned might not contain 'y', but if not, it is guaranteed
   1.175 +  // to be before any line which does contain 'y'.
   1.176 +  nsLineBox* GetFirstLineContaining(nscoord y);
   1.177 +  // Set the line cursor to our first line. Only call this if you
   1.178 +  // guarantee that the lines' combinedArea.ys and combinedArea.yMosts
   1.179 +  // are non-decreasing.
   1.180 +  void SetupLineCursor();
   1.181 +
   1.182 +  virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
   1.183 +  virtual bool IsVisibleInSelection(nsISelection* aSelection) MOZ_OVERRIDE;
   1.184 +
   1.185 +  virtual bool IsEmpty() MOZ_OVERRIDE;
   1.186 +  virtual bool CachedIsEmpty() MOZ_OVERRIDE;
   1.187 +  virtual bool IsSelfEmpty() MOZ_OVERRIDE;
   1.188 +
   1.189 +  // Given that we have a bullet, does it actually draw something, i.e.,
   1.190 +  // do we have either a 'list-style-type' or 'list-style-image' that is
   1.191 +  // not 'none'?
   1.192 +  bool BulletIsEmpty() const;
   1.193 +
   1.194 +  /**
   1.195 +   * Return the bullet text equivalent.
   1.196 +   */
   1.197 +  void GetBulletText(nsAString& aText) const;
   1.198 +
   1.199 +  /**
   1.200 +   * Return true if there's a bullet.
   1.201 +   */
   1.202 +  bool HasBullet() const {
   1.203 +    return HasOutsideBullet() || HasInsideBullet();
   1.204 +  }
   1.205 +
   1.206 +  /**
   1.207 +   * @return true if this frame has an inside bullet frame.
   1.208 +   */
   1.209 +  bool HasInsideBullet() const {
   1.210 +    return 0 != (mState & NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
   1.211 +  }
   1.212 +
   1.213 +  /**
   1.214 +   * @return true if this frame has an outside bullet frame.
   1.215 +   */
   1.216 +  bool HasOutsideBullet() const {
   1.217 +    return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
   1.218 +  }
   1.219 +
   1.220 +  /**
   1.221 +   * @return the bullet frame or nullptr if we don't have one.
   1.222 +   */
   1.223 +  nsBulletFrame* GetBullet() const {
   1.224 +    nsBulletFrame* outside = GetOutsideBullet();
   1.225 +    return outside ? outside : GetInsideBullet();
   1.226 +  }
   1.227 +
   1.228 +  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   1.229 +private:
   1.230 +  void CheckIntrinsicCacheAgainstShrinkWrapState();
   1.231 +public:
   1.232 +  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   1.233 +  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   1.234 +
   1.235 +  virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
   1.236 +  
   1.237 +  virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
   1.238 +                                           nscoord* aX,
   1.239 +                                           nscoord* aXMost) MOZ_OVERRIDE;
   1.240 +
   1.241 +  /**
   1.242 +   * Compute the final height of this frame.
   1.243 +   *
   1.244 +   * @param aReflowState Data structure passed from parent during reflow.
   1.245 +   * @param aReflowStatus A pointed to the reflow status for when we're finished
   1.246 +   *        doing reflow. this will get set appropriately if the height causes
   1.247 +   *        us to exceed the current available (page) height.
   1.248 +   * @param aContentHeight The height of content, precomputed outside of this
   1.249 +   *        function. The final height that is used in aMetrics will be set to
   1.250 +   *        either this or the available height, whichever is larger, in the
   1.251 +   *        case where our available height is constrained, and we overflow that
   1.252 +   *        available height.
   1.253 +   * @param aBorderPadding The margins representing the border padding for block
   1.254 +   *        frames. Can be 0.
   1.255 +   * @param aMetrics Out parameter for final height. Taken as an
   1.256 +   *        nsHTMLReflowMetrics object so that aMetrics can be passed in
   1.257 +   *        directly during reflow.
   1.258 +   * @param aConsumed The height already consumed by our previous-in-flows.
   1.259 +   */
   1.260 +  void ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
   1.261 +                          nsReflowStatus*          aStatus,
   1.262 +                          nscoord                  aContentHeight,
   1.263 +                          const nsMargin&          aBorderPadding,
   1.264 +                          nsHTMLReflowMetrics&     aMetrics,
   1.265 +                          nscoord                  aConsumed);
   1.266 +
   1.267 +  virtual nsresult Reflow(nsPresContext*           aPresContext,
   1.268 +                          nsHTMLReflowMetrics&     aDesiredSize,
   1.269 +                          const nsHTMLReflowState& aReflowState,
   1.270 +                          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   1.271 +
   1.272 +  virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
   1.273 +                                    nsIAtom*        aAttribute,
   1.274 +                                    int32_t         aModType) MOZ_OVERRIDE;
   1.275 +
   1.276 +  /**
   1.277 +   * Move any frames on our overflow list to the end of our principal list.
   1.278 +   * @return true if there were any overflow frames
   1.279 +   */
   1.280 +  virtual bool DrainSelfOverflowList() MOZ_OVERRIDE;
   1.281 +
   1.282 +  virtual nsresult StealFrame(nsIFrame* aChild,
   1.283 +                              bool      aForceNormal = false) MOZ_OVERRIDE;
   1.284 +
   1.285 +  virtual void DeleteNextInFlowChild(nsIFrame* aNextInFlow,
   1.286 +                                     bool      aDeletingEmptyFrames) MOZ_OVERRIDE;
   1.287 +
   1.288 +  /**
   1.289 +    * This is a special method that allows a child class of nsBlockFrame to
   1.290 +    * return a special, customized nsStyleText object to the nsLineLayout
   1.291 +    * constructor. It is used when the nsBlockFrame child needs to specify its
   1.292 +    * custom rendering style.
   1.293 +    */
   1.294 +  virtual const nsStyleText* StyleTextForLineLayout();
   1.295 +
   1.296 +  /**
   1.297 +   * Determines whether the collapsed margin carried out of the last
   1.298 +   * line includes the margin-top of a line with clearance (in which
   1.299 +   * case we must avoid collapsing that margin with our bottom margin)
   1.300 +   */
   1.301 +  bool CheckForCollapsedBottomMarginFromClearanceLine();
   1.302 +
   1.303 +  static nsresult GetCurrentLine(nsBlockReflowState *aState, nsLineBox **aOutCurrentLine);
   1.304 +
   1.305 +  /**
   1.306 +   * Determine if this block is a margin root at the top/bottom edges.
   1.307 +   */
   1.308 +  void IsMarginRoot(bool* aTopMarginRoot, bool* aBottomMarginRoot);
   1.309 +
   1.310 +  static bool BlockNeedsFloatManager(nsIFrame* aBlock);
   1.311 +
   1.312 +  /**
   1.313 +   * Returns whether aFrame is a block frame that will wrap its contents
   1.314 +   * around floats intruding on it from the outside.  (aFrame need not
   1.315 +   * be a block frame, but if it's not, the result will be false.)
   1.316 +   */
   1.317 +  static bool BlockCanIntersectFloats(nsIFrame* aFrame);
   1.318 +
   1.319 +  /**
   1.320 +   * Returns the width that needs to be cleared past floats for blocks
   1.321 +   * that cannot intersect floats.  aState must already have
   1.322 +   * GetAvailableSpace called on it for the vertical position that we
   1.323 +   * care about (which need not be its current mY)
   1.324 +   */
   1.325 +  struct ReplacedElementWidthToClear {
   1.326 +    nscoord marginLeft, borderBoxWidth, marginRight;
   1.327 +    nscoord MarginBoxWidth() const
   1.328 +      { return marginLeft + borderBoxWidth + marginRight; }
   1.329 +  };
   1.330 +  static ReplacedElementWidthToClear
   1.331 +    WidthToClearPastFloats(nsBlockReflowState& aState,
   1.332 +                           const nsRect& aFloatAvailableSpace,
   1.333 +                           nsIFrame* aFrame);
   1.334 +
   1.335 +  /**
   1.336 +   * Creates a contination for aFloat and adds it to the list of overflow floats.
   1.337 +   * Also updates aState.mReflowStatus to include the float's incompleteness.
   1.338 +   * Must only be called while this block frame is in reflow.
   1.339 +   * aFloatStatus must be the float's true, unmodified reflow status.
   1.340 +   * 
   1.341 +   */
   1.342 +  nsresult SplitFloat(nsBlockReflowState& aState,
   1.343 +                      nsIFrame*           aFloat,
   1.344 +                      nsReflowStatus      aFloatStatus);
   1.345 +
   1.346 +  /**
   1.347 +   * Walks up the frame tree, starting with aCandidate, and returns the first
   1.348 +   * block frame that it encounters.
   1.349 +   */
   1.350 +  static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate);
   1.351 +  
   1.352 +  struct FrameLines {
   1.353 +    nsLineList mLines;
   1.354 +    nsFrameList mFrames;
   1.355 +  };
   1.356 +
   1.357 +protected:
   1.358 +  nsBlockFrame(nsStyleContext* aContext)
   1.359 +    : nsContainerFrame(aContext)
   1.360 +    , mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
   1.361 +    , mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
   1.362 +  {
   1.363 +#ifdef DEBUG
   1.364 +  InitDebugFlags();
   1.365 +#endif
   1.366 +  }
   1.367 +  virtual ~nsBlockFrame();
   1.368 +
   1.369 +#ifdef DEBUG
   1.370 +  already_AddRefed<nsStyleContext> GetFirstLetterStyle(nsPresContext* aPresContext)
   1.371 +  {
   1.372 +    return aPresContext->StyleSet()->
   1.373 +      ProbePseudoElementStyle(mContent->AsElement(),
   1.374 +                              nsCSSPseudoElements::ePseudo_firstLetter,
   1.375 +                              mStyleContext);
   1.376 +  }
   1.377 +#endif
   1.378 +
   1.379 +  NS_DECLARE_FRAME_PROPERTY(LineCursorProperty, nullptr)
   1.380 +  nsLineBox* GetLineCursor() {
   1.381 +    return (GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR) ?
   1.382 +      static_cast<nsLineBox*>(Properties().Get(LineCursorProperty())) : nullptr;
   1.383 +  }
   1.384 +
   1.385 +  nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) {
   1.386 +    return NS_NewLineBox(PresContext()->PresShell(), aFrame, aIsBlock);
   1.387 +  }
   1.388 +  nsLineBox* NewLineBox(nsLineBox* aFromLine, nsIFrame* aFrame, int32_t aCount) {
   1.389 +    return NS_NewLineBox(PresContext()->PresShell(), aFromLine, aFrame, aCount);
   1.390 +  }
   1.391 +  void FreeLineBox(nsLineBox* aLine) {
   1.392 +    if (aLine == GetLineCursor()) {
   1.393 +      ClearLineCursor();
   1.394 +    }
   1.395 +    aLine->Destroy(PresContext()->PresShell());
   1.396 +  }
   1.397 +  /**
   1.398 +   * Helper method for StealFrame.
   1.399 +   */
   1.400 +  void RemoveFrameFromLine(nsIFrame* aChild, nsLineList::iterator aLine,
   1.401 +                           nsFrameList& aFrameList, nsLineList& aLineList);
   1.402 +
   1.403 +  void TryAllLines(nsLineList::iterator* aIterator,
   1.404 +                   nsLineList::iterator* aStartIterator,
   1.405 +                   nsLineList::iterator* aEndIterator,
   1.406 +                   bool*        aInOverflowLines,
   1.407 +                   FrameLines** aOverflowLines);
   1.408 +
   1.409 +  void SetFlags(nsFrameState aFlags) {
   1.410 +    mState &= ~NS_BLOCK_FLAGS_MASK;
   1.411 +    mState |= aFlags;
   1.412 +  }
   1.413 +
   1.414 +  /** move the frames contained by aLine by aDY
   1.415 +    * if aLine is a block, its child floats are added to the state manager
   1.416 +    */
   1.417 +  void SlideLine(nsBlockReflowState& aState,
   1.418 +                 nsLineBox* aLine, nscoord aDY);
   1.419 +
   1.420 +  void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
   1.421 +                        nsBlockReflowState&      aState,
   1.422 +                        nsHTMLReflowMetrics&     aMetrics,
   1.423 +                        nscoord*                 aBottomEdgeOfChildren);
   1.424 +
   1.425 +  void ComputeOverflowAreas(const nsRect&         aBounds,
   1.426 +                            const nsStyleDisplay* aDisplay,
   1.427 +                            nscoord               aBottomEdgeOfChildren,
   1.428 +                            nsOverflowAreas&      aOverflowAreas);
   1.429 +
   1.430 +  /**
   1.431 +   * Add the frames in aFrameList to this block after aPrevSibling.
   1.432 +   * This block thinks in terms of lines, but the frame construction code
   1.433 +   * knows nothing about lines at all so we need to find the line that
   1.434 +   * contains aPrevSibling and add aFrameList after aPrevSibling on that line.
   1.435 +   * New lines are created as necessary to handle block data in aFrameList.
   1.436 +   * This function will clear aFrameList.
   1.437 +   */
   1.438 +  void AddFrames(nsFrameList& aFrameList, nsIFrame* aPrevSibling);
   1.439 +
   1.440 +  /**
   1.441 +   * Perform Bidi resolution on this frame
   1.442 +   */
   1.443 +  nsresult ResolveBidi();
   1.444 +
   1.445 +  /**
   1.446 +   * Test whether the frame is a form control in a visual Bidi page.
   1.447 +   * This is necessary for backwards-compatibility, because most visual
   1.448 +   * pages use logical order for form controls so that they will
   1.449 +   * display correctly on native widgets in OSs with Bidi support
   1.450 +   * @param aPresContext the pres context
   1.451 +   * @return whether the frame is a BIDI form control
   1.452 +   */
   1.453 +  bool IsVisualFormControl(nsPresContext* aPresContext);
   1.454 +
   1.455 +public:
   1.456 +  /**
   1.457 +   * Does all the real work for removing aDeletedFrame
   1.458 +   * -- finds the line containing aDeletedFrame
   1.459 +   * -- removes all aDeletedFrame next-in-flows (or all continuations,
   1.460 +   * if REMOVE_FIXED_CONTINUATIONS is given)
   1.461 +   * -- marks lines dirty as needed
   1.462 +   * -- marks textruns dirty (unless FRAMES_ARE_EMPTY is given, in which
   1.463 +   * case textruns do not need to be dirtied)
   1.464 +   * -- destroys all removed frames
   1.465 +   */
   1.466 +  enum {
   1.467 +    REMOVE_FIXED_CONTINUATIONS = 0x02,
   1.468 +    FRAMES_ARE_EMPTY           = 0x04
   1.469 +  };
   1.470 +  nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags);
   1.471 +
   1.472 +  void ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
   1.473 +                      bool aReparentSiblings);
   1.474 +
   1.475 +  virtual bool UpdateOverflow() MOZ_OVERRIDE;
   1.476 +
   1.477 +  /** Load all of aFrame's floats into the float manager iff aFrame is not a
   1.478 +   *  block formatting context. Handles all necessary float manager translations;
   1.479 +   *  assumes float manager is in aFrame's parent's coord system.
   1.480 +   *  Safe to call on non-blocks (does nothing).
   1.481 +   */
   1.482 +  static void RecoverFloatsFor(nsIFrame*       aFrame,
   1.483 +                               nsFloatManager& aFloatManager);
   1.484 +
   1.485 +  /**
   1.486 +   * Determine if we have any pushed floats from a previous continuation.
   1.487 +   *
   1.488 +   * @returns true, if any of the floats at the beginning of our mFloats list
   1.489 +   *          have the NS_FRAME_IS_PUSHED_FLOAT bit set; false otherwise.
   1.490 +   */
   1.491 +  bool HasPushedFloatsFromPrevContinuation() const {
   1.492 +    if (!mFloats.IsEmpty()) {
   1.493 +      // If we have pushed floats, then they should be at the beginning of our
   1.494 +      // float list.
   1.495 +      if (mFloats.FirstChild()->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT) {
   1.496 +        return true;
   1.497 +      }
   1.498 +    }
   1.499 +
   1.500 +#ifdef DEBUG
   1.501 +    // Double-check the above assertion that pushed floats should be at the
   1.502 +    // beginning of our floats list.
   1.503 +    for (nsFrameList::Enumerator e(mFloats); !e.AtEnd(); e.Next()) {
   1.504 +      nsIFrame* f = e.get();
   1.505 +      NS_ASSERTION(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
   1.506 +        "pushed floats must be at the beginning of the float list");
   1.507 +    }
   1.508 +#endif
   1.509 +    return false;
   1.510 +  }
   1.511 +
   1.512 +protected:
   1.513 +
   1.514 +  /** grab overflow lines from this block's prevInFlow, and make them
   1.515 +    * part of this block's mLines list.
   1.516 +    * @return true if any lines were drained.
   1.517 +    */
   1.518 +  bool DrainOverflowLines();
   1.519 +
   1.520 +  /**
   1.521 +   * @return false iff this block does not have a float on any child list.
   1.522 +   * This function is O(1).
   1.523 +   */
   1.524 +  bool MaybeHasFloats() const {
   1.525 +    if (!mFloats.IsEmpty()) {
   1.526 +      return true;
   1.527 +    }
   1.528 +    // XXX this could be replaced with HasPushedFloats() if we enforced
   1.529 +    // removing the property when the frame list becomes empty.
   1.530 +    nsFrameList* list = GetPushedFloats();
   1.531 +    if (list && !list->IsEmpty()) {
   1.532 +      return true;
   1.533 +    }
   1.534 +    // For the OverflowOutOfFlowsProperty I think we do enforce that, but it's
   1.535 +    // a mix of out-of-flow frames, so that's why the method name has "Maybe".
   1.536 +    return GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS;
   1.537 +  }
   1.538 +
   1.539 +  /** grab pushed floats from this block's prevInFlow, and splice
   1.540 +    * them into this block's mFloats list.
   1.541 +    */
   1.542 +  void DrainPushedFloats(nsBlockReflowState& aState);
   1.543 +
   1.544 +  /** Load all our floats into the float manager (without reflowing them).
   1.545 +   *  Assumes float manager is in our own coordinate system.
   1.546 +   */
   1.547 +  void RecoverFloats(nsFloatManager& aFloatManager);
   1.548 +
   1.549 +  /** Reflow pushed floats
   1.550 +   */
   1.551 +  void ReflowPushedFloats(nsBlockReflowState& aState,
   1.552 +                          nsOverflowAreas&    aOverflowAreas,
   1.553 +                          nsReflowStatus&     aStatus);
   1.554 +
   1.555 +  /** Find any trailing BR clear from the last line of the block (or its PIFs)
   1.556 +   */
   1.557 +  uint8_t FindTrailingClear();
   1.558 +
   1.559 +  /**
   1.560 +   * Remove a float from our float list.
   1.561 +   */
   1.562 +  void RemoveFloat(nsIFrame* aFloat);
   1.563 +  /**
   1.564 +   * Remove a float from the float cache for the line its placeholder is on.
   1.565 +   */
   1.566 +  void RemoveFloatFromFloatCache(nsIFrame* aFloat);
   1.567 +
   1.568 +  void CollectFloats(nsIFrame* aFrame, nsFrameList& aList,
   1.569 +                     bool aCollectFromSiblings) {
   1.570 +    if (MaybeHasFloats()) {
   1.571 +      DoCollectFloats(aFrame, aList, aCollectFromSiblings);
   1.572 +    }
   1.573 +  }
   1.574 +  void DoCollectFloats(nsIFrame* aFrame, nsFrameList& aList,
   1.575 +                       bool aCollectFromSiblings);
   1.576 +
   1.577 +  // Remove a float, abs, rel positioned frame from the appropriate block's list
   1.578 +  static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
   1.579 +
   1.580 +  /** set up the conditions necessary for an resize reflow
   1.581 +    * the primary task is to mark the minimumly sufficient lines dirty. 
   1.582 +    */
   1.583 +  void PrepareResizeReflow(nsBlockReflowState& aState);
   1.584 +
   1.585 +  /** reflow all lines that have been marked dirty */
   1.586 +  nsresult ReflowDirtyLines(nsBlockReflowState& aState);
   1.587 +
   1.588 +  /** Mark a given line dirty due to reflow being interrupted on or before it */
   1.589 +  void MarkLineDirtyForInterrupt(nsLineBox* aLine);
   1.590 +
   1.591 +  //----------------------------------------
   1.592 +  // Methods for line reflow
   1.593 +  /**
   1.594 +   * Reflow a line.  
   1.595 +   * @param aState           the current reflow state
   1.596 +   * @param aLine            the line to reflow.  can contain a single block frame
   1.597 +   *                         or contain 1 or more inline frames.
   1.598 +   * @param aKeepReflowGoing [OUT] indicates whether the caller should continue to reflow more lines
   1.599 +   */
   1.600 +  nsresult ReflowLine(nsBlockReflowState& aState,
   1.601 +                      line_iterator aLine,
   1.602 +                      bool* aKeepReflowGoing);
   1.603 +
   1.604 +  // Return false if it needs another reflow because of reduced space
   1.605 +  // between floats that are next to it (but not next to its top), and
   1.606 +  // return true otherwise.
   1.607 +  bool PlaceLine(nsBlockReflowState& aState,
   1.608 +                   nsLineLayout&       aLineLayout,
   1.609 +                   line_iterator       aLine,
   1.610 +                   nsFloatManager::SavedState* aFloatStateBeforeLine,
   1.611 +                   nsRect&             aFloatAvailableSpace, /* in-out */
   1.612 +                   nscoord&            aAvailableSpaceHeight, /* in-out */
   1.613 +                   bool*             aKeepReflowGoing);
   1.614 +
   1.615 +  /**
   1.616 +    * If NS_BLOCK_LOOK_FOR_DIRTY_FRAMES is set, call MarkLineDirty
   1.617 +    * on any line with a child frame that is dirty.
   1.618 +    */
   1.619 +  void LazyMarkLinesDirty();
   1.620 +
   1.621 +  /**
   1.622 +   * Mark |aLine| dirty, and, if necessary because of possible
   1.623 +   * pull-up, mark the previous line dirty as well. Also invalidates textruns
   1.624 +   * on those lines because the text in the lines might have changed due to
   1.625 +   * addition/removal of frames.
   1.626 +   * @param aLine the line to mark dirty
   1.627 +   * @param aLineList the line list containing that line
   1.628 +   */
   1.629 +  void MarkLineDirty(line_iterator aLine, const nsLineList* aLineList);
   1.630 +
   1.631 +  // XXX where to go
   1.632 +  bool IsLastLine(nsBlockReflowState& aState,
   1.633 +                  line_iterator aLine);
   1.634 +
   1.635 +  void DeleteLine(nsBlockReflowState& aState,
   1.636 +                  nsLineList::iterator aLine,
   1.637 +                  nsLineList::iterator aLineEnd);
   1.638 +
   1.639 +  //----------------------------------------
   1.640 +  // Methods for individual frame reflow
   1.641 +
   1.642 +  bool ShouldApplyTopMargin(nsBlockReflowState& aState,
   1.643 +                              nsLineBox* aLine);
   1.644 +
   1.645 +  nsresult ReflowBlockFrame(nsBlockReflowState& aState,
   1.646 +                            line_iterator aLine,
   1.647 +                            bool* aKeepGoing);
   1.648 +
   1.649 +  nsresult ReflowInlineFrames(nsBlockReflowState& aState,
   1.650 +                              line_iterator aLine,
   1.651 +                              bool* aKeepLineGoing);
   1.652 +
   1.653 +  nsresult DoReflowInlineFrames(nsBlockReflowState& aState,
   1.654 +                                nsLineLayout& aLineLayout,
   1.655 +                                line_iterator aLine,
   1.656 +                                nsFlowAreaRect& aFloatAvailableSpace,
   1.657 +                                nscoord& aAvailableSpaceHeight,
   1.658 +                                nsFloatManager::SavedState*
   1.659 +                                  aFloatStateBeforeLine,
   1.660 +                                bool* aKeepReflowGoing,
   1.661 +                                LineReflowStatus* aLineReflowStatus,
   1.662 +                                bool aAllowPullUp);
   1.663 +
   1.664 +  nsresult ReflowInlineFrame(nsBlockReflowState& aState,
   1.665 +                             nsLineLayout& aLineLayout,
   1.666 +                             line_iterator aLine,
   1.667 +                             nsIFrame* aFrame,
   1.668 +                             LineReflowStatus* aLineReflowStatus);
   1.669 +
   1.670 +  // Compute the available width for a float. 
   1.671 +  nsRect AdjustFloatAvailableSpace(nsBlockReflowState& aState,
   1.672 +                                   const nsRect&       aFloatAvailableSpace,
   1.673 +                                   nsIFrame*           aFloatFrame);
   1.674 +  // Computes the border-box width of the float
   1.675 +  nscoord ComputeFloatWidth(nsBlockReflowState& aState,
   1.676 +                            const nsRect&       aFloatAvailableSpace,
   1.677 +                            nsIFrame*           aFloat);
   1.678 +  // An incomplete aReflowStatus indicates the float should be split
   1.679 +  // but only if the available height is constrained.
   1.680 +  // aAdjustedAvailableSpace is the result of calling
   1.681 +  // nsBlockFrame::AdjustFloatAvailableSpace.
   1.682 +  nsresult ReflowFloat(nsBlockReflowState& aState,
   1.683 +                       const nsRect&       aAdjustedAvailableSpace,
   1.684 +                       nsIFrame*           aFloat,
   1.685 +                       nsMargin&           aFloatMargin,
   1.686 +                       nsMargin&           aFloatOffsets,
   1.687 +                       // Whether the float's position
   1.688 +                       // (aAdjustedAvailableSpace) has been pushed down
   1.689 +                       // due to the presence of other floats.
   1.690 +                       bool                aFloatPushedDown,
   1.691 +                       nsReflowStatus&     aReflowStatus);
   1.692 +
   1.693 +  //----------------------------------------
   1.694 +  // Methods for pushing/pulling lines/frames
   1.695 +
   1.696 +  /**
   1.697 +   * Create a next-in-flow, if necessary, for aFrame. If a new frame is
   1.698 +   * created, place it in aLine if aLine is not null.
   1.699 +   * @param aState the block reflow state
   1.700 +   * @param aLine where to put a new frame
   1.701 +   * @param aFrame the frame
   1.702 +   * @return true if a new frame was created, false if not
   1.703 +   */
   1.704 +  bool CreateContinuationFor(nsBlockReflowState& aState,
   1.705 +                             nsLineBox*          aLine,
   1.706 +                             nsIFrame*           aFrame);
   1.707 +
   1.708 +  /**
   1.709 +   * Push aLine (and any after it), since it cannot be placed on this
   1.710 +   * page/column.  Set aKeepReflowGoing to false and set
   1.711 +   * flag aState.mReflowStatus as incomplete.
   1.712 +   */
   1.713 +  void PushTruncatedLine(nsBlockReflowState& aState,
   1.714 +                         line_iterator       aLine,
   1.715 +                         bool*               aKeepReflowGoing);
   1.716 +
   1.717 +  void SplitLine(nsBlockReflowState& aState,
   1.718 +                 nsLineLayout& aLineLayout,
   1.719 +                 line_iterator aLine,
   1.720 +                 nsIFrame* aFrame,
   1.721 +                 LineReflowStatus* aLineReflowStatus);
   1.722 +
   1.723 +  /**
   1.724 +   * Pull a frame from the next available location (one of our lines or
   1.725 +   * one of our next-in-flows lines).
   1.726 +   * @return the pulled frame or nullptr
   1.727 +   */
   1.728 +  nsIFrame* PullFrame(nsBlockReflowState& aState,
   1.729 +                      line_iterator       aLine);
   1.730 +
   1.731 +  /**
   1.732 +   * Try to pull a frame out of a line pointed at by aFromLine.
   1.733 +   *
   1.734 +   * Note: pulling a frame from a line that is a place-holder frame
   1.735 +   * doesn't automatically remove the corresponding float from the
   1.736 +   * line's float array. This happens indirectly: either the line gets
   1.737 +   * emptied (and destroyed) or the line gets reflowed (because we mark
   1.738 +   * it dirty) and the code at the top of ReflowLine empties the
   1.739 +   * array. So eventually, it will be removed, just not right away.
   1.740 +   *
   1.741 +   * @return the pulled frame or nullptr
   1.742 +   */
   1.743 +  nsIFrame* PullFrameFrom(nsLineBox*           aLine,
   1.744 +                          nsBlockFrame*        aFromContainer,
   1.745 +                          nsLineList::iterator aFromLine);
   1.746 +
   1.747 +  /**
   1.748 +   * Push the line after aLineBefore to the overflow line list.
   1.749 +   * @param aLineBefore a line in 'mLines' (or begin_lines() when
   1.750 +   *        pushing the first line)
   1.751 +   */
   1.752 +  void PushLines(nsBlockReflowState& aState,
   1.753 +                 nsLineList::iterator aLineBefore);
   1.754 +
   1.755 +  void PropagateFloatDamage(nsBlockReflowState& aState,
   1.756 +                            nsLineBox* aLine,
   1.757 +                            nscoord aDeltaY);
   1.758 +
   1.759 +  void CheckFloats(nsBlockReflowState& aState);
   1.760 +
   1.761 +  //----------------------------------------
   1.762 +  // List handling kludge
   1.763 +
   1.764 +  // If this returns true, the block it's called on should get the
   1.765 +  // NS_FRAME_HAS_DIRTY_CHILDREN bit set on it by the caller; either directly
   1.766 +  // if it's already in reflow, or via calling FrameNeedsReflow() to schedule a
   1.767 +  // reflow.
   1.768 +  bool RenumberLists(nsPresContext* aPresContext);
   1.769 +
   1.770 +  static bool RenumberListsInBlock(nsPresContext* aPresContext,
   1.771 +                                   nsBlockFrame* aBlockFrame,
   1.772 +                                   int32_t* aOrdinal,
   1.773 +                                   int32_t aDepth,
   1.774 +                                   int32_t aIncrement);
   1.775 +
   1.776 +  static bool RenumberListsFor(nsPresContext* aPresContext, nsIFrame* aKid,
   1.777 +                               int32_t* aOrdinal, int32_t aDepth,
   1.778 +                               int32_t aIncrement);
   1.779 +
   1.780 +  static bool FrameStartsCounterScope(nsIFrame* aFrame);
   1.781 +
   1.782 +  void ReflowBullet(nsIFrame* aBulletFrame,
   1.783 +                    nsBlockReflowState& aState,
   1.784 +                    nsHTMLReflowMetrics& aMetrics,
   1.785 +                    nscoord aLineTop);
   1.786 +
   1.787 +  //----------------------------------------
   1.788 +
   1.789 +  virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE;
   1.790 +
   1.791 +public:
   1.792 +  bool HasOverflowLines() const {
   1.793 +    return 0 != (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_LINES);
   1.794 +  }
   1.795 +  FrameLines* GetOverflowLines() const;
   1.796 +protected:
   1.797 +  FrameLines* RemoveOverflowLines();
   1.798 +  void SetOverflowLines(FrameLines* aOverflowLines);
   1.799 +  void DestroyOverflowLines();
   1.800 +
   1.801 +  /**
   1.802 +   * This class is useful for efficiently modifying the out of flow
   1.803 +   * overflow list. It gives the client direct writable access to
   1.804 +   * the frame list temporarily but ensures that property is only
   1.805 +   * written back if absolutely necessary.
   1.806 +   */
   1.807 +  struct nsAutoOOFFrameList {
   1.808 +    nsFrameList mList;
   1.809 +
   1.810 +    nsAutoOOFFrameList(nsBlockFrame* aBlock)
   1.811 +      : mPropValue(aBlock->GetOverflowOutOfFlows())
   1.812 +      , mBlock(aBlock) {
   1.813 +      if (mPropValue) {
   1.814 +        mList = *mPropValue;
   1.815 +      }
   1.816 +    }
   1.817 +    ~nsAutoOOFFrameList() {
   1.818 +      mBlock->SetOverflowOutOfFlows(mList, mPropValue);
   1.819 +    }
   1.820 +  protected:
   1.821 +    nsFrameList* const mPropValue;
   1.822 +    nsBlockFrame* const mBlock;
   1.823 +  };
   1.824 +  friend struct nsAutoOOFFrameList;
   1.825 +
   1.826 +  nsFrameList* GetOverflowOutOfFlows() const;
   1.827 +  void SetOverflowOutOfFlows(const nsFrameList& aList, nsFrameList* aPropValue);
   1.828 +
   1.829 +  /**
   1.830 +   * @return the inside bullet frame or nullptr if we don't have one.
   1.831 +   */
   1.832 +  nsBulletFrame* GetInsideBullet() const;
   1.833 +
   1.834 +  /**
   1.835 +   * @return the outside bullet frame or nullptr if we don't have one.
   1.836 +   */
   1.837 +  nsBulletFrame* GetOutsideBullet() const;
   1.838 +
   1.839 +  /**
   1.840 +   * @return the outside bullet frame list frame property.
   1.841 +   */
   1.842 +  nsFrameList* GetOutsideBulletList() const;
   1.843 +
   1.844 +  /**
   1.845 +   * @return true if this frame has pushed floats.
   1.846 +   */
   1.847 +  bool HasPushedFloats() const {
   1.848 +    return 0 != (GetStateBits() & NS_BLOCK_HAS_PUSHED_FLOATS);
   1.849 +  }
   1.850 +
   1.851 +  // Get the pushed floats list, which is used for *temporary* storage
   1.852 +  // of floats during reflow, between when we decide they don't fit in
   1.853 +  // this block until our next continuation takes them.
   1.854 +  nsFrameList* GetPushedFloats() const;
   1.855 +  // Get the pushed floats list, or if there is not currently one,
   1.856 +  // make a new empty one.
   1.857 +  nsFrameList* EnsurePushedFloats();
   1.858 +  // Remove and return the pushed floats list.
   1.859 +  nsFrameList* RemovePushedFloats();
   1.860 +
   1.861 +#ifdef DEBUG
   1.862 +  void VerifyLines(bool aFinalCheckOK);
   1.863 +  void VerifyOverflowSituation();
   1.864 +  int32_t GetDepth() const;
   1.865 +#endif
   1.866 +
   1.867 +  nscoord mMinWidth, mPrefWidth;
   1.868 +
   1.869 +  nsLineList mLines;
   1.870 +
   1.871 +  // List of all floats in this block
   1.872 +  // XXXmats blocks rarely have floats, make it a frame property
   1.873 +  nsFrameList mFloats;
   1.874 +
   1.875 +  friend class nsBlockReflowState;
   1.876 +  friend class nsBlockInFlowLineIterator;
   1.877 +
   1.878 +#ifdef DEBUG
   1.879 +public:
   1.880 +  static bool gLamePaintMetrics;
   1.881 +  static bool gLameReflowMetrics;
   1.882 +  static bool gNoisy;
   1.883 +  static bool gNoisyDamageRepair;
   1.884 +  static bool gNoisyIntrinsic;
   1.885 +  static bool gNoisyReflow;
   1.886 +  static bool gReallyNoisyReflow;
   1.887 +  static bool gNoisyFloatManager;
   1.888 +  static bool gVerifyLines;
   1.889 +  static bool gDisableResizeOpt;
   1.890 +
   1.891 +  static int32_t gNoiseIndent;
   1.892 +
   1.893 +  static const char* kReflowCommandType[];
   1.894 +
   1.895 +protected:
   1.896 +  static void InitDebugFlags();
   1.897 +#endif
   1.898 +};
   1.899 +
   1.900 +#ifdef DEBUG
   1.901 +class AutoNoisyIndenter {
   1.902 +public:
   1.903 +  AutoNoisyIndenter(bool aDoIndent) : mIndented(aDoIndent) {
   1.904 +    if (mIndented) {
   1.905 +      nsBlockFrame::gNoiseIndent++;
   1.906 +    }
   1.907 +  }
   1.908 +  ~AutoNoisyIndenter() {
   1.909 +    if (mIndented) {
   1.910 +      nsBlockFrame::gNoiseIndent--;
   1.911 +    }
   1.912 +  }
   1.913 +private:
   1.914 +  bool mIndented;
   1.915 +};
   1.916 +#endif
   1.917 +
   1.918 +/**
   1.919 + * Iterates over all lines in the prev-in-flows/next-in-flows of this block.
   1.920 + */
   1.921 +class nsBlockInFlowLineIterator {
   1.922 +public:
   1.923 +  typedef nsBlockFrame::line_iterator line_iterator;
   1.924 +  /**
   1.925 +   * Set up the iterator to point to aLine which must be a normal line
   1.926 +   * in aFrame (not an overflow line).
   1.927 +   */
   1.928 +  nsBlockInFlowLineIterator(nsBlockFrame* aFrame, line_iterator aLine);
   1.929 +  /**
   1.930 +   * Set up the iterator to point to the first line found starting from
   1.931 +   * aFrame. Sets aFoundValidLine to false if there is no such line.
   1.932 +   * After aFoundValidLine has returned false, don't call any methods on this
   1.933 +   * object again.
   1.934 +   */
   1.935 +  nsBlockInFlowLineIterator(nsBlockFrame* aFrame, bool* aFoundValidLine);
   1.936 +  /**
   1.937 +   * Set up the iterator to point to the line that contains aFindFrame (either
   1.938 +   * directly or indirectly).  If aFrame is out of flow, or contained in an
   1.939 +   * out-of-flow, finds the line containing the out-of-flow's placeholder. If
   1.940 +   * the frame is not found, sets aFoundValidLine to false. After
   1.941 +   * aFoundValidLine has returned false, don't call any methods on this
   1.942 +   * object again.
   1.943 +   */
   1.944 +  nsBlockInFlowLineIterator(nsBlockFrame* aFrame, nsIFrame* aFindFrame,
   1.945 +                            bool* aFoundValidLine);
   1.946 +
   1.947 +  line_iterator GetLine() { return mLine; }
   1.948 +  bool IsLastLineInList();
   1.949 +  nsBlockFrame* GetContainer() { return mFrame; }
   1.950 +  bool GetInOverflow() { return mLineList != &mFrame->mLines; }
   1.951 +
   1.952 +  /**
   1.953 +   * Returns the current line list we're iterating, null means
   1.954 +   * we're iterating |mLines| of the container.
   1.955 +   */
   1.956 +  nsLineList* GetLineList() { return mLineList; }
   1.957 +
   1.958 +  /**
   1.959 +   * Returns the end-iterator of whatever line list we're in.
   1.960 +   */
   1.961 +  line_iterator End();
   1.962 +
   1.963 +  /**
   1.964 +   * Returns false if there are no more lines. After this has returned false,
   1.965 +   * don't call any methods on this object again.
   1.966 +   */
   1.967 +  bool Next();
   1.968 +  /**
   1.969 +   * Returns false if there are no more lines. After this has returned false,
   1.970 +   * don't call any methods on this object again.
   1.971 +   */
   1.972 +  bool Prev();
   1.973 +
   1.974 +private:
   1.975 +  friend class nsBlockFrame;
   1.976 +  // XXX nsBlockFrame uses this internally in one place.  Try to remove it.
   1.977 +  nsBlockInFlowLineIterator(nsBlockFrame* aFrame, line_iterator aLine, bool aInOverflow);
   1.978 +
   1.979 +  nsBlockFrame* mFrame;
   1.980 +  line_iterator mLine;
   1.981 +  nsLineList*   mLineList;  // the line list mLine is in
   1.982 +
   1.983 +  /**
   1.984 +   * Moves iterator to next valid line reachable from the current block.
   1.985 +   * Returns false if there are no valid lines.
   1.986 +   */
   1.987 +  bool FindValidLine();
   1.988 +};
   1.989 +
   1.990 +#endif /* nsBlockFrame_h___ */

mercurial