LCOV - code coverage report
Current view: directory - layout/generic - nsContainerFrame.h (source / functions) Found Hit Coverage
Test: app.info Lines: 28 0 0.0 %
Date: 2012-06-02 Functions: 9 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Elika J. Etemad ("fantasai") <fantasai@inkedblade.net>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : /* base class #1 for rendering objects that have child lists */
      40                 : 
      41                 : #ifndef nsContainerFrame_h___
      42                 : #define nsContainerFrame_h___
      43                 : 
      44                 : #include "nsSplittableFrame.h"
      45                 : #include "nsFrameList.h"
      46                 : #include "nsLayoutUtils.h"
      47                 : #include "nsAutoPtr.h"
      48                 : 
      49                 : // Option flags for ReflowChild() and FinishReflowChild()
      50                 : // member functions
      51                 : #define NS_FRAME_NO_MOVE_VIEW         0x0001
      52                 : #define NS_FRAME_NO_MOVE_FRAME        (0x0002 | NS_FRAME_NO_MOVE_VIEW)
      53                 : #define NS_FRAME_NO_SIZE_VIEW         0x0004
      54                 : #define NS_FRAME_NO_VISIBILITY        0x0008
      55                 : // Only applies to ReflowChild: if true, invalidate the child if it's
      56                 : // being moved
      57                 : #define NS_FRAME_INVALIDATE_ON_MOVE   0x0010 
      58                 : 
      59                 : class nsOverflowContinuationTracker;
      60                 : 
      61                 : // Some macros for container classes to do sanity checking on
      62                 : // width/height/x/y values computed during reflow.
      63                 : // NOTE: AppUnitsPerCSSPixel value hardwired here to remove the
      64                 : // dependency on nsDeviceContext.h.  It doesn't matter if it's a
      65                 : // little off.
      66                 : #ifdef DEBUG
      67                 : #define CRAZY_W (1000000*60)
      68                 : #define CRAZY_H CRAZY_W
      69                 : 
      70                 : #define CRAZY_WIDTH(_x) (((_x) < -CRAZY_W) || ((_x) > CRAZY_W))
      71                 : #define CRAZY_HEIGHT(_y) (((_y) < -CRAZY_H) || ((_y) > CRAZY_H))
      72                 : #endif
      73                 : 
      74                 : /**
      75                 :  * Implementation of a container frame.
      76                 :  */
      77                 : class nsContainerFrame : public nsSplittableFrame
      78                 : {
      79                 : public:
      80                 :   NS_DECL_FRAMEARENA_HELPERS
      81                 :   NS_DECL_QUERYFRAME_TARGET(nsContainerFrame)
      82                 :   NS_DECL_QUERYFRAME
      83                 : 
      84                 :   // nsIFrame overrides
      85                 :   NS_IMETHOD Init(nsIContent* aContent,
      86                 :                   nsIFrame*   aParent,
      87                 :                   nsIFrame*   aPrevInFlow);
      88                 :   NS_IMETHOD SetInitialChildList(ChildListID  aListID,
      89                 :                                  nsFrameList& aChildList);
      90                 :   NS_IMETHOD AppendFrames(ChildListID  aListID,
      91                 :                           nsFrameList& aFrameList);
      92                 :   NS_IMETHOD InsertFrames(ChildListID aListID,
      93                 :                           nsIFrame* aPrevFrame,
      94                 :                           nsFrameList& aFrameList);
      95                 :   NS_IMETHOD RemoveFrame(ChildListID aListID,
      96                 :                          nsIFrame* aOldFrame);
      97                 : 
      98                 :   virtual const nsFrameList& GetChildList(ChildListID aList) const;
      99                 :   virtual void GetChildLists(nsTArray<ChildList>* aLists) const;
     100                 :   virtual void DestroyFrom(nsIFrame* aDestructRoot);
     101                 :   virtual void ChildIsDirty(nsIFrame* aChild);
     102                 : 
     103                 :   virtual bool IsLeaf() const;
     104                 :   virtual bool PeekOffsetNoAmount(bool aForward, PRInt32* aOffset);
     105                 :   virtual bool PeekOffsetCharacter(bool aForward, PRInt32* aOffset,
     106                 :                                      bool aRespectClusters = true);
     107                 :   
     108                 : #ifdef DEBUG
     109                 :   NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
     110                 : #endif  
     111                 : 
     112                 :   // nsContainerFrame methods
     113                 : 
     114                 :   /**
     115                 :    * Helper method to create next-in-flows if necessary. If aFrame
     116                 :    * already has a next-in-flow then this method does
     117                 :    * nothing. Otherwise, a new continuation frame is created and
     118                 :    * linked into the flow. In addition, the new frame is inserted
     119                 :    * into the principal child list after aFrame.
     120                 :    * @note calling this method on a block frame is illegal. Use
     121                 :    * nsBlockFrame::CreateContinuationFor() instead.
     122                 :    * @param aNextInFlowResult will contain the next-in-flow
     123                 :    *        <b>if and only if</b> one is created. If a next-in-flow already
     124                 :    *        exists aNextInFlowResult is set to nsnull.
     125                 :    * @return NS_OK if a next-in-flow already exists or is successfully created.
     126                 :    */
     127                 :   nsresult CreateNextInFlow(nsPresContext* aPresContext,
     128                 :                             nsIFrame*       aFrame,
     129                 :                             nsIFrame*&      aNextInFlowResult);
     130                 : 
     131                 :   /**
     132                 :    * Delete aNextInFlow and its next-in-flows.
     133                 :    * @param aDeletingEmptyFrames if set, then the reflow for aNextInFlow's
     134                 :    * content was complete before aNextInFlow, so aNextInFlow and its
     135                 :    * next-in-flows no longer map any real content.
     136                 :    */
     137                 :   virtual void DeleteNextInFlowChild(nsPresContext* aPresContext,
     138                 :                                      nsIFrame*      aNextInFlow,
     139                 :                                      bool           aDeletingEmptyFrames);
     140                 : 
     141                 :   /**
     142                 :    * Helper method to wrap views around frames. Used by containers
     143                 :    * under special circumstances (can be used by leaf frames as well)
     144                 :    */
     145                 :   static nsresult CreateViewForFrame(nsIFrame* aFrame,
     146                 :                                      bool aForce);
     147                 : 
     148                 :   // Positions the frame's view based on the frame's origin
     149                 :   static void PositionFrameView(nsIFrame* aKidFrame);
     150                 : 
     151                 :   static nsresult ReparentFrameView(nsPresContext* aPresContext,
     152                 :                                     nsIFrame*       aChildFrame,
     153                 :                                     nsIFrame*       aOldParentFrame,
     154                 :                                     nsIFrame*       aNewParentFrame);
     155                 : 
     156                 :   static nsresult ReparentFrameViewList(nsPresContext*     aPresContext,
     157                 :                                         const nsFrameList& aChildFrameList,
     158                 :                                         nsIFrame*          aOldParentFrame,
     159                 :                                         nsIFrame*          aNewParentFrame);
     160                 : 
     161                 :   // Set the view's size and position after its frame has been reflowed.
     162                 :   //
     163                 :   // Flags:
     164                 :   // NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
     165                 :   //    don't want to automatically sync the frame and view
     166                 :   // NS_FRAME_NO_SIZE_VIEW - don't size the view
     167                 :   static void SyncFrameViewAfterReflow(nsPresContext* aPresContext,
     168                 :                                        nsIFrame*       aFrame,
     169                 :                                        nsIView*        aView,
     170                 :                                        const nsRect&   aVisualOverflowArea,
     171                 :                                        PRUint32        aFlags = 0);
     172                 : 
     173                 :   // Syncs properties to the top level view and window, like transparency and
     174                 :   // shadow.
     175                 :   static void SyncWindowProperties(nsPresContext*       aPresContext,
     176                 :                                    nsIFrame*            aFrame,
     177                 :                                    nsIView*             aView);
     178                 : 
     179                 :   // Sets the view's attributes from the frame style.
     180                 :   // - visibility
     181                 :   // - clip
     182                 :   // Call this when one of these styles changes or when the view has just
     183                 :   // been created.
     184                 :   // @param aStyleContext can be null, in which case the frame's style context is used
     185                 :   static void SyncFrameViewProperties(nsPresContext*  aPresContext,
     186                 :                                       nsIFrame*        aFrame,
     187                 :                                       nsStyleContext*  aStyleContext,
     188                 :                                       nsIView*         aView,
     189                 :                                       PRUint32         aFlags = 0);
     190                 : 
     191                 :   // Used by both nsInlineFrame and nsFirstLetterFrame.
     192                 :   void DoInlineIntrinsicWidth(nsRenderingContext *aRenderingContext,
     193                 :                               InlineIntrinsicWidthData *aData,
     194                 :                               nsLayoutUtils::IntrinsicWidthType aType);
     195                 : 
     196                 :   /**
     197                 :    * This is the CSS block concept of computing 'auto' widths, which most
     198                 :    * classes derived from nsContainerFrame want.
     199                 :    */
     200                 :   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
     201                 :                                  nsSize aCBSize, nscoord aAvailableWidth,
     202                 :                                  nsSize aMargin, nsSize aBorder,
     203                 :                                  nsSize aPadding, bool aShrinkWrap);
     204                 : 
     205                 :   /**
     206                 :    * Invokes the WillReflow() function, positions the frame and its view (if
     207                 :    * requested), and then calls Reflow(). If the reflow succeeds and the child
     208                 :    * frame is complete, deletes any next-in-flows using DeleteNextInFlowChild()
     209                 :    *
     210                 :    * Flags:
     211                 :    * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
     212                 :    *    don't want to automatically sync the frame and view
     213                 :    * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
     214                 :    *    case. Also implies NS_FRAME_NO_MOVE_VIEW
     215                 :    */
     216                 :   nsresult ReflowChild(nsIFrame*                      aKidFrame,
     217                 :                        nsPresContext*                 aPresContext,
     218                 :                        nsHTMLReflowMetrics&           aDesiredSize,
     219                 :                        const nsHTMLReflowState&       aReflowState,
     220                 :                        nscoord                        aX,
     221                 :                        nscoord                        aY,
     222                 :                        PRUint32                       aFlags,
     223                 :                        nsReflowStatus&                aStatus,
     224                 :                        nsOverflowContinuationTracker* aTracker = nsnull);
     225                 : 
     226                 :   /**
     227                 :    * The second half of frame reflow. Does the following:
     228                 :    * - sets the frame's bounds
     229                 :    * - sizes and positions (if requested) the frame's view. If the frame's final
     230                 :    *   position differs from the current position and the frame itself does not
     231                 :    *   have a view, then any child frames with views are positioned so they stay
     232                 :    *   in sync
     233                 :    * - sets the view's visibility, opacity, content transparency, and clip
     234                 :    * - invoked the DidReflow() function
     235                 :    *
     236                 :    * Flags:
     237                 :    * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
     238                 :    *    case. Also implies NS_FRAME_NO_MOVE_VIEW
     239                 :    * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
     240                 :    *    don't want to automatically sync the frame and view
     241                 :    * NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
     242                 :    */
     243                 :   static nsresult FinishReflowChild(nsIFrame*                  aKidFrame,
     244                 :                                     nsPresContext*             aPresContext,
     245                 :                                     const nsHTMLReflowState*   aReflowState,
     246                 :                                     const nsHTMLReflowMetrics& aDesiredSize,
     247                 :                                     nscoord                    aX,
     248                 :                                     nscoord                    aY,
     249                 :                                     PRUint32                   aFlags);
     250                 : 
     251                 :   
     252                 :   static void PositionChildViews(nsIFrame* aFrame);
     253                 : 
     254                 :   // ==========================================================================
     255                 :   /* Overflow containers are continuation frames that hold overflow. They
     256                 :    * are created when the frame runs out of computed height, but still has
     257                 :    * too much content to fit in the availableHeight. The parent creates a
     258                 :    * continuation as usual, but marks it as NS_FRAME_IS_OVERFLOW_CONTAINER
     259                 :    * and adds it to its next-in-flow's overflow container list, either by
     260                 :    * adding it directly or by putting it in its own excess overflow containers
     261                 :    * list (to be drained by the next-in-flow when it calls
     262                 :    * ReflowOverflowContainerChildren). The parent continues reflow as if
     263                 :    * the frame was complete once it ran out of computed height, but returns
     264                 :    * either an NS_FRAME_NOT_COMPLETE or NS_FRAME_OVERFLOW_INCOMPLETE reflow
     265                 :    * status to request a next-in-flow. The parent's next-in-flow is then
     266                 :    * responsible for calling ReflowOverflowContainerChildren to (drain and)
     267                 :    * reflow these overflow continuations. Overflow containers do not affect
     268                 :    * other frames' size or position during reflow (but do affect their
     269                 :    * parent's overflow area).
     270                 :    *
     271                 :    * Overflow container continuations are different from normal continuations
     272                 :    * in that
     273                 :    *   - more than one child of the frame can have its next-in-flow broken
     274                 :    *     off and pushed into the frame's next-in-flow
     275                 :    *   - new continuations may need to be spliced into the middle of the list
     276                 :    *     or deleted continuations slipped out
     277                 :    *     e.g. A, B, C are all fixed-size containers on one page, all have
     278                 :    *      overflow beyond availableHeight, and content is dynamically added
     279                 :    *      and removed from B
     280                 :    * As a result, it is not possible to simply prepend the new continuations
     281                 :    * to the old list as with the overflowProperty mechanism. To avoid
     282                 :    * complicated list splicing, the code assumes only one overflow containers
     283                 :    * list exists for a given frame: either its own overflowContainersProperty
     284                 :    * or its prev-in-flow's excessOverflowContainersProperty, not both.
     285                 :    *
     286                 :    * The nsOverflowContinuationTracker helper class should be used for tracking
     287                 :    * overflow containers and adding them to the appropriate list.
     288                 :    * See nsBlockFrame::Reflow for a sample implementation.
     289                 :    */
     290                 : 
     291                 :   friend class nsOverflowContinuationTracker;
     292                 : 
     293                 :   /**
     294                 :    * Reflow overflow container children. They are invisible to normal reflow
     295                 :    * (i.e. don't affect sizing or placement of other children) and inherit
     296                 :    * width and horizontal position from their prev-in-flow.
     297                 :    *
     298                 :    * This method
     299                 :    *   1. Pulls excess overflow containers from the prev-in-flow and adds
     300                 :    *      them to our overflow container list
     301                 :    *   2. Reflows all our overflow container kids
     302                 :    *   3. Expands aOverflowRect as necessary to accomodate these children.
     303                 :    *   4. Sets aStatus's NS_FRAME_OVERFLOW_IS_INCOMPLETE flag (along with
     304                 :    *      NS_FRAME_REFLOW_NEXTINFLOW as necessary) if any overflow children
     305                 :    *      are incomplete and
     306                 :    *   5. Prepends a list of their continuations to our excess overflow
     307                 :    *      container list, to be drained into our next-in-flow when it is
     308                 :    *      reflowed.
     309                 :    *
     310                 :    * The caller is responsible for tracking any new overflow container
     311                 :    * continuations it makes, removing them from its child list, and
     312                 :    * making sure they are stored properly in the overflow container lists.
     313                 :    * The nsOverflowContinuationTracker helper class should be used for this.
     314                 :    *
     315                 :    * (aFlags just gets passed through to ReflowChild)
     316                 :    */
     317                 :   nsresult ReflowOverflowContainerChildren(nsPresContext*           aPresContext,
     318                 :                                            const nsHTMLReflowState& aReflowState,
     319                 :                                            nsOverflowAreas&         aOverflowRects,
     320                 :                                            PRUint32                 aFlags,
     321                 :                                            nsReflowStatus&          aStatus);
     322                 : 
     323                 :   /**
     324                 :    * Removes aChild without destroying it and without requesting reflow.
     325                 :    * Continuations are not affected. Checks the primary and overflow
     326                 :    * or overflow containers and excess overflow containers lists, depending
     327                 :    * on whether the NS_FRAME_IS_OVERFLOW_CONTAINER flag is set. Does not
     328                 :    * check any other auxiliary lists.
     329                 :    * Returns NS_ERROR_UNEXPECTED if we failed to remove aChild.
     330                 :    * Returns other error codes if we failed to put back a proptable list.
     331                 :    * If aForceNormal is true, only checks the primary and overflow lists
     332                 :    * even when the NS_FRAME_IS_OVERFLOW_CONTAINER flag is set.
     333                 :    */
     334                 :   virtual nsresult StealFrame(nsPresContext* aPresContext,
     335                 :                               nsIFrame*      aChild,
     336                 :                               bool           aForceNormal = false);
     337                 : 
     338                 :   /**
     339                 :    * Removes the next-siblings of aChild without destroying them and without
     340                 :    * requesting reflow. Checks the principal and overflow lists (not
     341                 :    * overflow containers / excess overflow containers). Does not check any
     342                 :    * other auxiliary lists.
     343                 :    * @param aChild a child frame or nsnull
     344                 :    * @return If aChild is non-null, the next-siblings of aChild, if any.
     345                 :    *         If aChild is null, all child frames on the principal list, if any.
     346                 :    */
     347                 :   nsFrameList StealFramesAfter(nsIFrame* aChild);
     348                 : 
     349                 :   /**
     350                 :    * Add overflow containers to the display list
     351                 :    */
     352                 :   void DisplayOverflowContainers(nsDisplayListBuilder*   aBuilder,
     353                 :                                  const nsRect&           aDirtyRect,
     354                 :                                  const nsDisplayListSet& aLists);
     355                 : 
     356                 :   /**
     357                 :    * Builds display lists for the children. The background
     358                 :    * of each child is placed in the Content() list (suitable for inline
     359                 :    * children and other elements that behave like inlines,
     360                 :    * but not for in-flow block children of blocks).  DOES NOT
     361                 :    * paint the background/borders/outline of this frame. This should
     362                 :    * probably be avoided and eventually removed. It's currently here
     363                 :    * to emulate what nsContainerFrame::Paint did.
     364                 :    */
     365                 :   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     366                 :                               const nsRect&           aDirtyRect,
     367                 :                               const nsDisplayListSet& aLists);
     368                 : 
     369                 :   // Destructor function for the proptable-stored framelists
     370               0 :   static void DestroyFrameList(void* aPropertyValue)
     371                 :   {
     372               0 :     if (aPropertyValue) {
     373               0 :       static_cast<nsFrameList*>(aPropertyValue)->Destroy();
     374                 :     }
     375               0 :   }
     376                 : 
     377               0 :   NS_DECLARE_FRAME_PROPERTY(OverflowProperty, DestroyFrameList)
     378               0 :   NS_DECLARE_FRAME_PROPERTY(OverflowContainersProperty, DestroyFrameList)
     379               0 :   NS_DECLARE_FRAME_PROPERTY(ExcessOverflowContainersProperty, DestroyFrameList)
     380                 : 
     381                 : protected:
     382               0 :   nsContainerFrame(nsStyleContext* aContext) : nsSplittableFrame(aContext) {}
     383                 :   ~nsContainerFrame();
     384                 : 
     385                 :   /**
     386                 :    * Builds a display list for non-block children that behave like
     387                 :    * inlines. This puts the background of each child into the
     388                 :    * Content() list (suitable for inline children but not for
     389                 :    * in-flow block children of blocks).
     390                 :    * @param aForcePseudoStack forces each child into a pseudo-stacking-context
     391                 :    * so its background and all other display items (except for positioned
     392                 :    * display items) go into the Content() list.
     393                 :    */
     394                 :   nsresult BuildDisplayListForNonBlockChildren(nsDisplayListBuilder*   aBuilder,
     395                 :                                                const nsRect&           aDirtyRect,
     396                 :                                                const nsDisplayListSet& aLists,
     397                 :                                                PRUint32                aFlags = 0);
     398                 : 
     399                 :   /**
     400                 :    * A version of BuildDisplayList that use DISPLAY_CHILD_INLINE.
     401                 :    * Intended as a convenience for derived classes.
     402                 :    */
     403               0 :   nsresult BuildDisplayListForInline(nsDisplayListBuilder*   aBuilder,
     404                 :                                      const nsRect&           aDirtyRect,
     405                 :                                      const nsDisplayListSet& aLists) {
     406               0 :     nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
     407               0 :     NS_ENSURE_SUCCESS(rv, rv);
     408                 :     rv = BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists,
     409               0 :                                              DISPLAY_CHILD_INLINE);
     410               0 :     NS_ENSURE_SUCCESS(rv, rv);
     411               0 :     return rv;
     412                 :   }
     413                 : 
     414                 : 
     415                 :   // ==========================================================================
     416                 :   /* Overflow Frames are frames that did not fit and must be pulled by
     417                 :    * our next-in-flow during its reflow. (The same concept for overflow
     418                 :    * containers is called "excess frames". We should probably make the
     419                 :    * names match.)
     420                 :    */
     421                 : 
     422                 :   /**
     423                 :    * Get the frames on the overflow list.  Can return null if there are no
     424                 :    * overflow frames.  The caller does NOT take ownership of the list; it's
     425                 :    * still owned by this frame.  A non-null return value indicates that the
     426                 :    * list is nonempty.
     427                 :    */
     428                 :   inline nsFrameList* GetOverflowFrames() const;
     429                 : 
     430                 :   /**
     431                 :    * As GetOverflowFrames, but removes the overflow frames property.  The
     432                 :    * caller is responsible for deleting nsFrameList and either passing
     433                 :    * ownership of the frames to someone else or destroying the frames.  A
     434                 :    * non-null return value indicates that the list is nonempty.  The
     435                 :    * recommended way to use this function it to assign its return value
     436                 :    * into an nsAutoPtr.
     437                 :    */
     438                 :   inline nsFrameList* StealOverflowFrames();
     439                 :   
     440                 :   /**
     441                 :    * Set the overflow list.  aOverflowFrames must not be an empty list.
     442                 :    */
     443                 :   void SetOverflowFrames(nsPresContext*  aPresContext,
     444                 :                          const nsFrameList& aOverflowFrames);
     445                 : 
     446                 :   /**
     447                 :    * Destroy the overflow list and any frames that are on it.
     448                 :    * Calls DestructFrom() insead of Destruct() on the frames if
     449                 :    * aDestructRoot is non-null.
     450                 :    */
     451                 :   void DestroyOverflowList(nsPresContext* aPresContext,
     452                 :                            nsIFrame*      aDestructRoot);
     453                 : 
     454                 :   /**
     455                 :    * Moves any frames on both the prev-in-flow's overflow list and the
     456                 :    * receiver's overflow to the receiver's child list.
     457                 :    *
     458                 :    * Resets the overlist pointers to nsnull, and updates the receiver's child
     459                 :    * count and content mapping.
     460                 :    *
     461                 :    * @return true if any frames were moved and false otherwise
     462                 :    */
     463                 :   bool MoveOverflowToChildList(nsPresContext* aPresContext);
     464                 : 
     465                 :   /**
     466                 :    * Push aFromChild and its next siblings to the next-in-flow. Change
     467                 :    * the geometric parent of each frame that's pushed. If there is no
     468                 :    * next-in-flow the frames are placed on the overflow list (and the
     469                 :    * geometric parent is left unchanged).
     470                 :    *
     471                 :    * Updates the next-in-flow's child count. Does <b>not</b> update the
     472                 :    * pusher's child count.
     473                 :    *
     474                 :    * @param   aFromChild the first child frame to push. It is disconnected from
     475                 :    *            aPrevSibling
     476                 :    * @param   aPrevSibling aFromChild's previous sibling. Must not be null.
     477                 :    *            It's an error to push a parent's first child frame
     478                 :    */
     479                 :   void PushChildren(nsPresContext*  aPresContext,
     480                 :                     nsIFrame*       aFromChild,
     481                 :                     nsIFrame*       aPrevSibling);
     482                 : 
     483                 :   // ==========================================================================
     484                 :   /*
     485                 :    * Convenience methods for nsFrameLists stored in the
     486                 :    * PresContext's proptable
     487                 :    */
     488                 : 
     489                 :   /**
     490                 :    * Get the PresContext-stored nsFrameList named aPropID for this frame.
     491                 :    * May return null.
     492                 :    */
     493                 :   nsFrameList* GetPropTableFrames(nsPresContext*                 aPresContext,
     494                 :                                   const FramePropertyDescriptor* aProperty) const;
     495                 : 
     496                 :   /**
     497                 :    * Remove and return the PresContext-stored nsFrameList named aPropID for
     498                 :    * this frame. May return null.
     499                 :    */
     500                 :   nsFrameList* RemovePropTableFrames(nsPresContext*                 aPresContext,
     501                 :                                      const FramePropertyDescriptor* aProperty);
     502                 : 
     503                 :   /**
     504                 :    * Remove aFrame from the PresContext-stored nsFrameList named aPropID
     505                 :    * for this frame, deleting the list if it is now empty.
     506                 :    * Return true if the aFrame was successfully removed,
     507                 :    * Return false otherwise.
     508                 :    */
     509                 :   bool RemovePropTableFrame(nsPresContext*                 aPresContext,
     510                 :                               nsIFrame*                      aFrame,
     511                 :                               const FramePropertyDescriptor* aProperty);
     512                 : 
     513                 :   /**
     514                 :    * Set the PresContext-stored nsFrameList named aPropID for this frame
     515                 :    * to the given aFrameList, which must not be null.
     516                 :    */
     517                 :   nsresult SetPropTableFrames(nsPresContext*                 aPresContext,
     518                 :                               nsFrameList*                   aFrameList,
     519                 :                               const FramePropertyDescriptor* aProperty);
     520                 :   // ==========================================================================
     521                 : 
     522                 :   nsFrameList mFrames;
     523                 : };
     524                 : 
     525                 : // ==========================================================================
     526                 : /* The out-of-flow-related code below is for a hacky way of splitting
     527                 :  * absolutely-positioned frames. Basically what we do is split the frame
     528                 :  * in nsAbsoluteContainingBlock and pretend the continuation is an overflow
     529                 :  * container. This isn't an ideal solution, but it lets us print the content
     530                 :  * at least. See bug 154892.
     531                 :  */
     532                 : 
     533                 : #define IS_TRUE_OVERFLOW_CONTAINER(frame)                      \
     534                 :   (  (frame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)  \
     535                 :   && !( (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&      \
     536                 :         frame->GetStyleDisplay()->IsAbsolutelyPositioned()  )  )
     537                 : //XXXfr This check isn't quite correct, because it doesn't handle cases
     538                 : //      where the out-of-flow has overflow.. but that's rare.
     539                 : //      We'll need to revisit the way abspos continuations are handled later
     540                 : //      for various reasons, this detail is one of them. See bug 154892
     541                 : 
     542                 : /**
     543                 :  * Helper class for tracking overflow container continuations during reflow.
     544                 :  *
     545                 :  * A frame is related to two sets of overflow containers: those that /are/
     546                 :  * its own children, and those that are /continuations/ of its children.
     547                 :  * This tracker walks through those continuations (the frame's NIF's children)
     548                 :  * and their prev-in-flows (a subset of the frame's normal and overflow
     549                 :  * container children) in parallel. It allows the reflower to synchronously
     550                 :  * walk its overflow continuations while it loops through and reflows its
     551                 :  * children. This makes it possible to insert new continuations at the correct
     552                 :  * place in the overflow containers list.
     553                 :  *
     554                 :  * The reflower is expected to loop through its children in the same order it
     555                 :  * looped through them the last time (if there was a last time).
     556                 :  * For each child, the reflower should either
     557                 :  *   - call Skip for the child if was not reflowed in this pass
     558                 :  *   - call Insert for the overflow continuation if the child was reflowed
     559                 :  *     but has incomplete overflow
     560                 :  *   - call Finished for the child if it was reflowed in this pass but
     561                 :  *     is either complete or has a normal next-in-flow. This call can
     562                 :  *     be skipped if the child did not previously have an overflow
     563                 :  *     continuation.
     564                 :  */
     565                 : class nsOverflowContinuationTracker {
     566                 : public:
     567                 :   /**
     568                 :    * Initializes an nsOverflowContinuationTracker to help track overflow
     569                 :    * continuations of aFrame's children. Typically invoked on 'this'.
     570                 :    *
     571                 :    * aWalkOOFFrames determines whether the walker skips out-of-flow frames
     572                 :    * or skips non-out-of-flow frames.
     573                 :    *
     574                 :    * Don't set aSkipOverflowContainerChildren to false unless you plan
     575                 :    * to walk your own overflow container children. (Usually they are handled
     576                 :    * by calling ReflowOverflowContainerChildren.) aWalkOOFFrames is ignored
     577                 :    * if aSkipOverflowContainerChildren is false.
     578                 :    */
     579                 :   nsOverflowContinuationTracker(nsPresContext*    aPresContext,
     580                 :                                 nsContainerFrame* aFrame,
     581                 :                                 bool              aWalkOOFFrames,
     582                 :                                 bool              aSkipOverflowContainerChildren = true);
     583                 :   /**
     584                 :    * This function adds an overflow continuation to our running list and
     585                 :    * sets its NS_FRAME_IS_OVERFLOW_CONTAINER flag.
     586                 :    *
     587                 :    * aReflowStatus should preferably be specific to the recently-reflowed
     588                 :    * child and not influenced by any of its siblings' statuses. This
     589                 :    * function sets the NS_FRAME_IS_DIRTY bit on aOverflowCont if it needs
     590                 :    * to be reflowed. (Its need for reflow depends on changes to its
     591                 :    * prev-in-flow, not to its parent--for whom it is invisible, reflow-wise.)
     592                 :    *
     593                 :    * The caller MUST disconnect the frame from its parent's child list
     594                 :    * if it was not previously an NS_FRAME_IS_OVERFLOW_CONTAINER (because
     595                 :    * StealFrame is much more inefficient than disconnecting in place
     596                 :    * during Reflow, which the caller is able to do but we are not).
     597                 :    *
     598                 :    * The caller MUST NOT disconnect the frame from its parent's
     599                 :    * child list if it is already an NS_FRAME_IS_OVERFLOW_CONTAINER.
     600                 :    * (In this case we will disconnect and reconnect it ourselves.)
     601                 :    */
     602                 :   nsresult Insert(nsIFrame*       aOverflowCont,
     603                 :                   nsReflowStatus& aReflowStatus);
     604                 :   /**
     605                 :    * This function must be called for each child that is reflowed
     606                 :    * but no longer has an overflow continuation. (It may be called for
     607                 :    * other children, but in that case has no effect.) It increments our
     608                 :    * walker and makes sure we drop any dangling pointers to its
     609                 :    * next-in-flow. This function MUST be called before stealing or
     610                 :    * deleting aChild's next-in-flow.
     611                 :    */
     612                 :   void Finish(nsIFrame* aChild);
     613                 : 
     614                 :   /**
     615                 :    * This function should be called for each child that isn't reflowed.
     616                 :    * It increments our walker and sets the NS_FRAME_OVERFLOW_INCOMPLETE
     617                 :    * reflow flag if it encounters an overflow continuation so that our
     618                 :    * next-in-flow doesn't get prematurely deleted. It MUST be called on
     619                 :    * each unreflowed child that has an overflow container continuation;
     620                 :    * it MAY be called on other children, but it isn't necessary (doesn't
     621                 :    * do anything).
     622                 :    */
     623               0 :   void Skip(nsIFrame* aChild, nsReflowStatus& aReflowStatus)
     624                 :   {
     625               0 :     NS_PRECONDITION(aChild, "null ptr");
     626               0 :     if (aChild == mSentry) {
     627               0 :       StepForward();
     628               0 :       NS_MergeReflowStatusInto(&aReflowStatus, NS_FRAME_OVERFLOW_INCOMPLETE);
     629                 :     }
     630               0 :   }
     631                 : 
     632                 : private:
     633                 : 
     634                 :   void SetUpListWalker();
     635                 :   void StepForward();
     636                 : 
     637                 :   /* We hold a pointer to either the next-in-flow's overflow containers list
     638                 :      or, if that doesn't exist, our frame's excess overflow containers list.
     639                 :      We need to make sure that we drop that pointer if the list becomes
     640                 :      empty and is deleted elsewhere. */
     641                 :   nsFrameList* mOverflowContList;
     642                 :   /* We hold a pointer to the most recently-reflowed child that has an
     643                 :      overflow container next-in-flow. We do this because it's a known
     644                 :      good point; this pointer won't be deleted on us. We can use it to
     645                 :      recover our place in the list. */
     646                 :   nsIFrame* mPrevOverflowCont;
     647                 :   /* This is a pointer to the next overflow container's prev-in-flow, which
     648                 :      is (or should be) a child of our frame. When we hit this, we will need
     649                 :      to increment this walker to the next overflow container. */
     650                 :   nsIFrame* mSentry;
     651                 :   /* Parent of all frames in mOverflowContList. If our mOverflowContList
     652                 :      is an excessOverflowContainersProperty, or null, then this is our frame
     653                 :      (the frame that was passed in to our constructor). Otherwise this is
     654                 :      that frame's next-in-flow, and our mOverflowContList is mParent's
     655                 :      overflowContainersProperty */
     656                 :   nsContainerFrame* mParent;
     657                 :   /* Tells SetUpListWalker whether or not to walk us past any continuations
     658                 :      of overflow containers. aWalkOOFFrames is ignored when this is false. */
     659                 :   bool mSkipOverflowContainerChildren;
     660                 :   /* Tells us whether to pay attention to OOF frames or non-OOF frames */
     661                 :   bool mWalkOOFFrames;
     662                 : };
     663                 : 
     664                 : inline
     665                 : nsFrameList*
     666               0 : nsContainerFrame::GetOverflowFrames() const
     667                 : {
     668                 :   nsFrameList* list =
     669               0 :     static_cast<nsFrameList*>(Properties().Get(OverflowProperty()));
     670               0 :   NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
     671               0 :   return list;
     672                 : }
     673                 : 
     674                 : inline
     675                 : nsFrameList*
     676               0 : nsContainerFrame::StealOverflowFrames()
     677                 : {
     678                 :   nsFrameList* list =
     679               0 :     static_cast<nsFrameList*>(Properties().Remove(OverflowProperty()));
     680               0 :   NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
     681               0 :   return list;
     682                 : }
     683                 : 
     684                 : #endif /* nsContainerFrame_h___ */

Generated by: LCOV version 1.7