LCOV - app.info - layout/generic/nsContainerFrame.h

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-04-21 | 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