LCOV - code coverage report
Current view: directory - objdir/dist/include - nsFrameList.h (source / functions) Found Hit Coverage
Test: app.info Lines: 27 4 14.8 %
Date: 2012-06-02 Functions: 10 2 20.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 Communicator client 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                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef nsFrameList_h___
      39                 : #define nsFrameList_h___
      40                 : 
      41                 : #include "nscore.h"
      42                 : #include "nsTraceRefcnt.h"
      43                 : #include <stdio.h> /* for FILE* */
      44                 : #include "nsDebug.h"
      45                 : #include "nsTArray.h"
      46                 : 
      47                 : class nsIFrame;
      48                 : namespace mozilla {
      49                 : namespace layout {
      50                 :   class FrameChildList;
      51                 :   enum FrameChildListID {
      52                 :       // The individual concrete child lists.
      53                 :       kPrincipalList                = 0x1,
      54                 :       kPopupList                    = 0x2,
      55                 :       kCaptionList                  = 0x4,
      56                 :       kColGroupList                 = 0x8,
      57                 :       kSelectPopupList              = 0x10,
      58                 :       kAbsoluteList                 = 0x20,
      59                 :       kFixedList                    = 0x40,
      60                 :       kOverflowList                 = 0x80,
      61                 :       kOverflowContainersList       = 0x100,
      62                 :       kExcessOverflowContainersList = 0x200,
      63                 :       kOverflowOutOfFlowList        = 0x400,
      64                 :       kFloatList                    = 0x800,
      65                 :       kBulletList                   = 0x1000,
      66                 :       kPushedFloatsList             = 0x2000,
      67                 :       // A special alias for kPrincipalList that suppress the reflow request that
      68                 :       // is normally done when manipulating child lists.
      69                 :       kNoReflowPrincipalList        = 0x4000
      70                 :   };
      71                 : }
      72                 : }
      73                 : 
      74                 : // Uncomment this to enable expensive frame-list integrity checking
      75                 : // #define DEBUG_FRAME_LIST
      76                 : 
      77                 : /**
      78                 :  * A class for managing a list of frames.
      79                 :  */
      80                 : class nsFrameList {
      81                 : public:
      82                 :   nsFrameList() :
      83                 :     mFirstChild(nsnull), mLastChild(nsnull)
      84                 :   {
      85                 :     MOZ_COUNT_CTOR(nsFrameList);
      86                 :   }
      87                 : 
      88                 :   nsFrameList(nsIFrame* aFirstFrame, nsIFrame* aLastFrame) :
      89                 :     mFirstChild(aFirstFrame), mLastChild(aLastFrame)
      90                 :   {
      91                 :     MOZ_COUNT_CTOR(nsFrameList);
      92                 :     VerifyList();
      93                 :   }
      94                 : 
      95               0 :   nsFrameList(const nsFrameList& aOther) :
      96               0 :     mFirstChild(aOther.mFirstChild), mLastChild(aOther.mLastChild)
      97                 :   {
      98               0 :     MOZ_COUNT_CTOR(nsFrameList);
      99               0 :   }
     100                 : 
     101            1403 :   ~nsFrameList() {
     102            1403 :     MOZ_COUNT_DTOR(nsFrameList);
     103                 :     // Don't destroy our frames here, so that we can have temporary nsFrameLists
     104            1403 :   }
     105                 : 
     106                 :   /**
     107                 :    * For each frame in this list: remove it from the list then call
     108                 :    * Destroy() on it.
     109                 :    */
     110                 :   void DestroyFrames();
     111                 : 
     112                 :   /**
     113                 :    * For each frame in this list: remove it from the list then call
     114                 :    * DestroyFrom() on it.
     115                 :    */
     116                 :   void DestroyFramesFrom(nsIFrame* aDestructRoot);
     117                 : 
     118                 :   /**
     119                 :    * For each frame in this list: remove it from the list then call
     120                 :    * Destroy() on it. Finally <code>delete this</code>.
     121                 :    * 
     122                 :    */
     123                 :   void Destroy();
     124                 : 
     125                 :   /**
     126                 :    * For each frame in this list: remove it from the list then call
     127                 :    * DestroyFrom() on it. Finally <code>delete this</code>.
     128                 :    *
     129                 :    */
     130                 :   void DestroyFrom(nsIFrame* aDestructRoot);
     131                 : 
     132                 :   void Clear() { mFirstChild = mLastChild = nsnull; }
     133                 : 
     134                 :   void SetFrames(nsIFrame* aFrameList);
     135                 : 
     136                 :   void SetFrames(nsFrameList& aFrameList) {
     137                 :     NS_PRECONDITION(!mFirstChild, "Losing frames");
     138                 : 
     139                 :     mFirstChild = aFrameList.FirstChild();
     140                 :     mLastChild = aFrameList.LastChild();
     141                 :     aFrameList.Clear();
     142                 :   }
     143                 : 
     144                 :   class Slice;
     145                 : 
     146                 :   /**
     147                 :    * Append aFrameList to this list.  If aParent is not null,
     148                 :    * reparents the newly added frames.  Clears out aFrameList and
     149                 :    * returns a list slice represening the newly-appended frames.
     150                 :    */
     151                 :   Slice AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
     152                 :     return InsertFrames(aParent, LastChild(), aFrameList);
     153                 :   }
     154                 : 
     155                 : 
     156                 :   /**
     157                 :    * Append aFrame to this list.  If aParent is not null,
     158                 :    * reparents the newly added frame.
     159                 :    */
     160                 :   void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame) {
     161                 :     nsFrameList temp(aFrame, aFrame);
     162                 :     AppendFrames(aParent, temp);
     163                 :   }
     164                 : 
     165                 :   /**
     166                 :    * Take aFrame out of the frame list. This also disconnects aFrame
     167                 :    * from the sibling list. The frame must be non-null and present on
     168                 :    * this list.
     169                 :    */
     170                 :   void RemoveFrame(nsIFrame* aFrame);
     171                 : 
     172                 :   /**
     173                 :    * Take aFrame out of the frame list, if present. This also disconnects
     174                 :    * aFrame from the sibling list. aFrame must be non-null but is not
     175                 :    * required to be on the list.
     176                 :    * @return true if aFrame was removed
     177                 :    */
     178                 :   bool RemoveFrameIfPresent(nsIFrame* aFrame);
     179                 : 
     180                 :   /**
     181                 :    * Take the frames after aAfterFrame out of the frame list.  If
     182                 :    * aAfterFrame is null, removes the entire list.
     183                 :    * @param aAfterFrame a frame in this list, or null
     184                 :    * @return the removed frames, if any
     185                 :    */
     186                 :   nsFrameList RemoveFramesAfter(nsIFrame* aAfterFrame);
     187                 : 
     188                 :   /**
     189                 :    * Take the first frame (if any) out of the frame list.
     190                 :    * @return the first child, or nsnull if the list is empty
     191                 :    */
     192                 :   nsIFrame* RemoveFirstChild();
     193                 : 
     194                 :   /**
     195                 :    * Take aFrame out of the frame list and then destroy it.
     196                 :    * The frame must be non-null and present on this list.
     197                 :    */
     198                 :   void DestroyFrame(nsIFrame* aFrame);
     199                 : 
     200                 :   /**
     201                 :    * If aFrame is present on this list then take it out of the list and
     202                 :    * then destroy it. The frame must be non-null.
     203                 :    * @return true if the frame was found
     204                 :    */
     205                 :   bool DestroyFrameIfPresent(nsIFrame* aFrame);
     206                 : 
     207                 :   /**
     208                 :    * Insert aFrame right after aPrevSibling, or prepend it to this
     209                 :    * list if aPrevSibling is null. If aParent is not null, also
     210                 :    * reparents newly-added frame. Note that this method always
     211                 :    * sets the frame's nextSibling pointer.
     212                 :    */
     213                 :   void InsertFrame(nsIFrame* aParent, nsIFrame* aPrevSibling,
     214                 :                    nsIFrame* aFrame) {
     215                 :     nsFrameList temp(aFrame, aFrame);
     216                 :     InsertFrames(aParent, aPrevSibling, temp);
     217                 :   }
     218                 : 
     219                 : 
     220                 :   /**
     221                 :    * Inserts aFrameList into this list after aPrevSibling (at the beginning if
     222                 :    * aPrevSibling is null).  If aParent is not null, reparents the newly added
     223                 :    * frames.  Clears out aFrameList and returns a list slice representing the
     224                 :    * newly-inserted frames.
     225                 :    */
     226                 :   Slice InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
     227                 :                      nsFrameList& aFrameList);
     228                 : 
     229                 :   class FrameLinkEnumerator;
     230                 : 
     231                 :   /**
     232                 :    * Split this frame list such that all the frames before the link pointed to
     233                 :    * by aLink end up in the returned list, while the remaining frames stay in
     234                 :    * this list.  After this call, aLink points to the beginning of this list.
     235                 :    */
     236                 :   nsFrameList ExtractHead(FrameLinkEnumerator& aLink);
     237                 : 
     238                 :   /**
     239                 :    * Split this frame list such that all the frames coming after the link
     240                 :    * pointed to by aLink end up in the returned list, while the frames before
     241                 :    * that link stay in this list.  After this call, aLink is at end.
     242                 :    */
     243                 :   nsFrameList ExtractTail(FrameLinkEnumerator& aLink);
     244                 : 
     245               0 :   nsIFrame* FirstChild() const {
     246               0 :     return mFirstChild;
     247                 :   }
     248                 : 
     249               0 :   nsIFrame* LastChild() const {
     250               0 :     return mLastChild;
     251                 :   }
     252                 : 
     253                 :   nsIFrame* FrameAt(PRInt32 aIndex) const;
     254                 :   PRInt32 IndexOf(nsIFrame* aFrame) const;
     255                 : 
     256                 :   bool IsEmpty() const {
     257                 :     return nsnull == mFirstChild;
     258                 :   }
     259                 : 
     260                 :   bool NotEmpty() const {
     261                 :     return nsnull != mFirstChild;
     262                 :   }
     263                 : 
     264                 :   bool ContainsFrame(const nsIFrame* aFrame) const;
     265                 : 
     266                 :   PRInt32 GetLength() const;
     267                 : 
     268                 :   /**
     269                 :    * If this frame list has only one frame, return that frame.
     270                 :    * Otherwise, return null.
     271                 :    */
     272                 :   nsIFrame* OnlyChild() const {
     273                 :     if (FirstChild() == LastChild()) {
     274                 :       return FirstChild();
     275                 :     }
     276                 :     return nsnull;
     277                 :   }
     278                 : 
     279                 :   /**
     280                 :    * Call SetParent(aParent) for each frame in this list.
     281                 :    * @param aParent the new parent frame, must be non-null
     282                 :    */
     283                 :   void ApplySetParent(nsIFrame* aParent) const;
     284                 : 
     285                 :   /**
     286                 :    * If this frame list is non-empty then append it to aLists as the
     287                 :    * aListID child list.
     288                 :    * (this method is implemented in FrameChildList.h for dependency reasons)
     289                 :    */
     290                 :   inline void AppendIfNonempty(nsTArray<mozilla::layout::FrameChildList>* aLists,
     291                 :                                mozilla::layout::FrameChildListID aListID) const;
     292                 : 
     293                 : #ifdef IBMBIDI
     294                 :   /**
     295                 :    * Return the frame before this frame in visual order (after Bidi reordering).
     296                 :    * If aFrame is null, return the last frame in visual order.
     297                 :    */
     298                 :   nsIFrame* GetPrevVisualFor(nsIFrame* aFrame) const;
     299                 : 
     300                 :   /**
     301                 :    * Return the frame after this frame in visual order (after Bidi reordering).
     302                 :    * If aFrame is null, return the first frame in visual order.
     303                 :    */
     304                 :   nsIFrame* GetNextVisualFor(nsIFrame* aFrame) const;
     305                 : #endif // IBMBIDI
     306                 : 
     307                 : #ifdef DEBUG
     308                 :   void List(FILE* out) const;
     309                 : #endif
     310                 : 
     311                 :   static void Init();
     312            2806 :   static void Shutdown() { delete sEmptyList; }
     313                 :   static const nsFrameList& EmptyList() { return *sEmptyList; }
     314                 : 
     315                 :   class Enumerator;
     316                 : 
     317                 :   /**
     318                 :    * A class representing a slice of a frame list.
     319                 :    */
     320                 :   class Slice {
     321                 :     friend class Enumerator;
     322                 : 
     323                 :   public:
     324                 :     // Implicit on purpose, so that we can easily create enumerators from
     325                 :     // nsFrameList via this impicit constructor.
     326               0 :     Slice(const nsFrameList& aList) :
     327                 : #ifdef DEBUG
     328                 :       mList(aList),
     329                 : #endif
     330               0 :       mStart(aList.FirstChild()),
     331               0 :       mEnd(nsnull)
     332               0 :     {}
     333                 : 
     334                 :     Slice(const nsFrameList& aList, nsIFrame* aStart, nsIFrame* aEnd) :
     335                 : #ifdef DEBUG
     336                 :       mList(aList),
     337                 : #endif
     338                 :       mStart(aStart),
     339                 :       mEnd(aEnd)
     340                 :     {}
     341                 : 
     342               0 :     Slice(const Slice& aOther) :
     343                 : #ifdef DEBUG
     344                 :       mList(aOther.mList),
     345                 : #endif
     346                 :       mStart(aOther.mStart),
     347               0 :       mEnd(aOther.mEnd)
     348               0 :     {}
     349                 : 
     350                 :   private:
     351                 : #ifdef DEBUG
     352                 :     const nsFrameList& mList;
     353                 : #endif
     354                 :     nsIFrame* const mStart; // our starting frame
     355                 :     const nsIFrame* const mEnd; // The first frame that is NOT in the slice.
     356                 :                                 // May be null.
     357                 :   };
     358                 : 
     359                 :   class Enumerator {
     360                 :   public:
     361               0 :     Enumerator(const Slice& aSlice) :
     362                 : #ifdef DEBUG
     363                 :       mSlice(aSlice),
     364                 : #endif
     365                 :       mFrame(aSlice.mStart),
     366               0 :       mEnd(aSlice.mEnd)
     367               0 :     {}
     368                 : 
     369                 :     Enumerator(const Enumerator& aOther) :
     370                 : #ifdef DEBUG
     371                 :       mSlice(aOther.mSlice),
     372                 : #endif
     373                 :       mFrame(aOther.mFrame),
     374                 :       mEnd(aOther.mEnd)
     375                 :     {}
     376                 : 
     377               0 :     bool AtEnd() const {
     378                 :       // Can't just check mEnd, because some table code goes and destroys the
     379                 :       // tail of the frame list (including mEnd!) while iterating over the
     380                 :       // frame list.
     381               0 :       return !mFrame || mFrame == mEnd;
     382                 :     }
     383                 : 
     384                 :     /* Next() needs to know about nsIFrame, and nsIFrame will need to
     385                 :        know about nsFrameList methods, so in order to inline this put
     386                 :        the implementation in nsIFrame.h */
     387                 :     inline void Next();
     388                 : 
     389                 :     /**
     390                 :      * Get the current frame we're pointing to.  Do not call this on an
     391                 :      * iterator that is at end!
     392                 :      */
     393               0 :     nsIFrame* get() const {
     394               0 :       NS_PRECONDITION(!AtEnd(), "Enumerator is at end");
     395               0 :       return mFrame;
     396                 :     }
     397                 : 
     398                 :     /**
     399                 :      * Get an enumerator that is just like this one, but not limited in terms of
     400                 :      * the part of the list it will traverse.
     401                 :      */
     402                 :     Enumerator GetUnlimitedEnumerator() const {
     403                 :       return Enumerator(*this, nsnull);
     404                 :     }
     405                 : 
     406                 : #ifdef DEBUG
     407                 :     const nsFrameList& List() const { return mSlice.mList; }
     408                 : #endif
     409                 : 
     410                 :   protected:
     411                 :     Enumerator(const Enumerator& aOther, const nsIFrame* const aNewEnd):
     412                 : #ifdef DEBUG
     413                 :       mSlice(aOther.mSlice),
     414                 : #endif
     415                 :       mFrame(aOther.mFrame),
     416                 :       mEnd(aNewEnd)
     417                 :     {}
     418                 : 
     419                 : #ifdef DEBUG
     420                 :     /* Has to be an object, not a reference, since the slice could
     421                 :        well be a temporary constructed from an nsFrameList */
     422                 :     const Slice mSlice;
     423                 : #endif
     424                 :     nsIFrame* mFrame; // our current frame.
     425                 :     const nsIFrame* const mEnd; // The first frame we should NOT enumerate.
     426                 :                                 // May be null.
     427                 :   };
     428                 : 
     429                 :   /**
     430                 :    * A class that can be used to enumerate links between frames.  When created
     431                 :    * from an nsFrameList, it points to the "link" immediately before the first
     432                 :    * frame.  It can then be advanced until it points to the "link" immediately
     433                 :    * after the last frame.  At any position, PrevFrame() and NextFrame() are
     434                 :    * the frames before and after the given link.  This means PrevFrame() is
     435                 :    * null when the enumerator is at the beginning of the list and NextFrame()
     436                 :    * is null when it's AtEnd().
     437                 :    */
     438                 :   class FrameLinkEnumerator : private Enumerator {
     439                 :   public:
     440                 :     friend class nsFrameList;
     441                 : 
     442                 :     FrameLinkEnumerator(const nsFrameList& aList) :
     443                 :       Enumerator(aList),
     444                 :       mPrev(nsnull)
     445                 :     {}
     446                 : 
     447                 :     FrameLinkEnumerator(const FrameLinkEnumerator& aOther) :
     448                 :       Enumerator(aOther),
     449                 :       mPrev(aOther.mPrev)
     450                 :     {}
     451                 : 
     452                 :     /* This constructor needs to know about nsIFrame, and nsIFrame will need to
     453                 :        know about nsFrameList methods, so in order to inline this put
     454                 :        the implementation in nsIFrame.h */
     455                 :     inline FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame);
     456                 : 
     457                 :     void operator=(const FrameLinkEnumerator& aOther) {
     458                 :       NS_PRECONDITION(&List() == &aOther.List(), "Different lists?");
     459                 :       mFrame = aOther.mFrame;
     460                 :       mPrev = aOther.mPrev;
     461                 :     }
     462                 : 
     463                 :     void Next() {
     464                 :       mPrev = mFrame;
     465                 :       Enumerator::Next();
     466                 :     }
     467                 : 
     468                 :     bool AtEnd() const { return Enumerator::AtEnd(); }
     469                 : 
     470                 :     nsIFrame* PrevFrame() const { return mPrev; }
     471                 :     nsIFrame* NextFrame() const { return mFrame; }
     472                 : 
     473                 :   protected:
     474                 :     nsIFrame* mPrev;
     475                 :   };
     476                 : 
     477                 : private:
     478                 : #ifdef DEBUG_FRAME_LIST
     479                 :   void VerifyList() const;
     480                 : #else
     481                 :   void VerifyList() const {}
     482                 : #endif
     483                 : 
     484                 :   static const nsFrameList* sEmptyList;
     485                 : 
     486                 : protected:
     487                 :   nsIFrame* mFirstChild;
     488                 :   nsIFrame* mLastChild;
     489                 : };
     490                 : 
     491                 : #endif /* nsFrameList_h___ */

Generated by: LCOV version 1.7