LCOV - code coverage report
Current view: directory - content/svg/content/src - DOMSVGPathSegList.h (source / functions) Found Hit Coverage
Test: app.info Lines: 23 1 4.3 %
Date: 2012-06-02 Functions: 14 1 7.1 %

       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 SVG Project code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is the Mozilla Foundation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *
      23                 :  * Alternatively, the contents of this file may be used under the terms of
      24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      27                 :  * of those above. If you wish to allow use of your version of this file only
      28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      29                 :  * use your version of this file under the terms of the MPL, indicate your
      30                 :  * decision by deleting the provisions above and replace them with the notice
      31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      32                 :  * the provisions above, a recipient may use your version of this file under
      33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      34                 :  *
      35                 :  * ***** END LICENSE BLOCK ***** */
      36                 : 
      37                 : #ifndef MOZILLA_DOMSVGPATHSEGLIST_H__
      38                 : #define MOZILLA_DOMSVGPATHSEGLIST_H__
      39                 : 
      40                 : #include "nsAutoPtr.h"
      41                 : #include "nsCOMPtr.h"
      42                 : #include "nsCycleCollectionParticipant.h"
      43                 : #include "nsDebug.h"
      44                 : #include "nsIDOMSVGPathSegList.h"
      45                 : #include "nsSVGElement.h"
      46                 : #include "nsTArray.h"
      47                 : #include "SVGPathData.h" // IWYU pragma: keep
      48                 : 
      49                 : class nsIDOMSVGPathSeg;
      50                 : 
      51                 : namespace mozilla {
      52                 : 
      53                 : class DOMSVGPathSeg;
      54                 : class SVGAnimatedPathSegList;
      55                 : 
      56                 : /**
      57                 :  * Class DOMSVGPathSegList
      58                 :  *
      59                 :  * This class is used to create the DOM tearoff objects that wrap internal
      60                 :  * SVGPathData objects.
      61                 :  *
      62                 :  * See the architecture comment in DOMSVGAnimatedLengthList.h first (that's
      63                 :  * LENGTH list), then continue reading the remainder of this comment.
      64                 :  *
      65                 :  * The architecture of this class is very similar to that of DOMSVGLengthList
      66                 :  * except that, since there is no nsIDOMSVGAnimatedPathSegList interface
      67                 :  * in SVG, we have no parent DOMSVGAnimatedPathSegList (unlike DOMSVGLengthList
      68                 :  * which has a parent DOMSVGAnimatedLengthList class). (There is an
      69                 :  * SVGAnimatedPathData interface, but that is quite different to
      70                 :  * DOMSVGAnimatedLengthList, since it is inherited by elements rather than
      71                 :  * elements having members of that type.) As a consequence, much of the logic
      72                 :  * that would otherwise be in DOMSVGAnimatedPathSegList (and is in
      73                 :  * DOMSVGAnimatedLengthList) is contained in this class.
      74                 :  *
      75                 :  * This class is strongly intertwined with DOMSVGPathSeg. Our DOMSVGPathSeg
      76                 :  * items are friends of us and responsible for nulling out our pointers to
      77                 :  * them when they die.
      78                 :  *
      79                 :  * Our DOM items are created lazily on demand as and when script requests them.
      80                 :  */
      81                 : class DOMSVGPathSegList : public nsIDOMSVGPathSegList,
      82                 :                           public nsWrapperCache
      83                 : {
      84                 :   friend class DOMSVGPathSeg;
      85                 : 
      86                 : public:
      87               0 :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      88            1464 :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPathSegList)
      89                 :   NS_DECL_NSIDOMSVGPATHSEGLIST
      90                 : 
      91                 :   virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
      92                 :                                bool *triedToWrap);
      93                 : 
      94               0 :   nsISupports* GetParentObject()
      95                 :   {
      96               0 :     return static_cast<nsIContent*>(mElement);
      97                 :   }
      98                 : 
      99                 :   /**
     100                 :    * Factory method to create and return a DOMSVGPathSegList wrapper
     101                 :    * for a given internal SVGPathData object. The factory takes care
     102                 :    * of caching the object that it returns so that the same object can be
     103                 :    * returned for the given SVGPathData each time it is requested.
     104                 :    * The cached object is only removed from the cache when it is destroyed due
     105                 :    * to there being no more references to it or to any of its descendant
     106                 :    * objects. If that happens, any subsequent call requesting the DOM wrapper
     107                 :    * for the SVGPathData will naturally result in a new
     108                 :    * DOMSVGPathSegList being returned.
     109                 :    *
     110                 :    * It's unfortunate that aList is a void* instead of a typed argument. This
     111                 :    * is because the mBaseVal and mAnimVal members of SVGAnimatedPathSegList are
     112                 :    * of different types - a plain SVGPathData, and a SVGPathData*. We
     113                 :    * use the addresses of these members as the key for the hash table, and
     114                 :    * clearly SVGPathData* and a SVGPathData** are not the same type.
     115                 :    */
     116                 :   static already_AddRefed<DOMSVGPathSegList>
     117                 :   GetDOMWrapper(void *aList,
     118                 :                 nsSVGElement *aElement,
     119                 :                 bool aIsAnimValList);
     120                 : 
     121                 :   /**
     122                 :    * This method returns the DOMSVGPathSegList wrapper for an internal
     123                 :    * SVGPathData object if it currently has a wrapper. If it does
     124                 :    * not, then nsnull is returned.
     125                 :    */
     126                 :   static DOMSVGPathSegList*
     127                 :   GetDOMWrapperIfExists(void *aList);
     128                 : 
     129                 :   /**
     130                 :    * This will normally be the same as InternalList().CountItems(), except if
     131                 :    * we've hit OOM, in which case our length will be zero.
     132                 :    */
     133               0 :   PRUint32 Length() const {
     134               0 :     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
     135                 :                       mItems.Length() == InternalList().CountItems(),
     136                 :                       "DOM wrapper's list length is out of sync");
     137               0 :     return mItems.Length();
     138                 :   }
     139                 : 
     140                 :   /**
     141                 :    * WATCH OUT! If you add code to call this on a baseVal wrapper, then you
     142                 :    * must also call it on the animVal wrapper too if necessary!! See other
     143                 :    * callers!
     144                 :    *
     145                 :    * Called by internal code to notify us when we need to sync the length of
     146                 :    * this DOM list with its internal list. This is called immediately prior to
     147                 :    * the length of the internal list being changed so that any DOM list items
     148                 :    * that need to be removed from the DOM list can first copy their values from
     149                 :    * their internal counterpart.
     150                 :    *
     151                 :    * The only time this method could fail is on OOM when trying to increase the
     152                 :    * length of the DOM list. If that happens then this method simply clears the
     153                 :    * list and returns. Callers just proceed as normal, and we simply accept
     154                 :    * that the DOM list will be empty (until successfully set to a new value).
     155                 :    */
     156                 :   void InternalListWillChangeTo(const SVGPathData& aNewValue);
     157                 : 
     158                 :   /**
     159                 :    * Returns true if our attribute is animating (in which case our animVal is
     160                 :    * not simply a mirror of our baseVal).
     161                 :    */
     162                 :   bool AttrIsAnimating() const;
     163                 : 
     164                 : private:
     165                 : 
     166                 :   /**
     167                 :    * Only our static GetDOMWrapper() factory method may create objects of our
     168                 :    * type.
     169                 :    */
     170               0 :   DOMSVGPathSegList(nsSVGElement *aElement, bool aIsAnimValList)
     171                 :     : mElement(aElement)
     172               0 :     , mIsAnimValList(aIsAnimValList)
     173                 :   {
     174               0 :     SetIsProxy();
     175                 : 
     176               0 :     InternalListWillChangeTo(InternalList()); // Sync mItems
     177               0 :   }
     178                 : 
     179                 :   ~DOMSVGPathSegList();
     180                 : 
     181               0 :   nsSVGElement* Element() {
     182               0 :     return mElement.get();
     183                 :   }
     184                 : 
     185                 :   /// Used to determine if this list is the baseVal or animVal list.
     186               0 :   bool IsAnimValList() const {
     187               0 :     return mIsAnimValList;
     188                 :   }
     189                 : 
     190                 :   /**
     191                 :    * Get a reference to this object's corresponding internal SVGPathData.
     192                 :    *
     193                 :    * To simplify the code we just have this one method for obtaining both
     194                 :    * base val and anim val internal lists. This means that anim val lists don't
     195                 :    * get const protection, but our setter methods guard against changing
     196                 :    * anim val lists.
     197                 :    */
     198                 :   SVGPathData& InternalList() const;
     199                 : 
     200                 :   SVGAnimatedPathSegList& InternalAList() const;
     201                 : 
     202                 :   /// Creates an instance of the appropriate DOMSVGPathSeg sub-class for
     203                 :   // aIndex, if it doesn't already exist.
     204                 :   void EnsureItemAt(PRUint32 aIndex);
     205                 : 
     206                 :   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex,
     207                 :                                       PRUint32 aInternalIndex,
     208                 :                                       PRUint32 aArgCountForItem);
     209                 :   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex,
     210                 :                                         PRUint32 aArgCountForItem);
     211                 : 
     212                 :   // Calls UpdateListIndex on all elements in |mItems| that satisfy ItemAt(),
     213                 :   // from |aStartingIndex| to the end of |mItems|.  Also adjusts
     214                 :   // |mItems.mInternalDataIndex| by the requested amount.
     215                 :   void UpdateListIndicesFromIndex(PRUint32 aStartingIndex,
     216                 :                                   PRInt32  aInternalDataIndexDelta);
     217                 : 
     218               0 :   DOMSVGPathSeg*& ItemAt(PRUint32 aIndex) {
     219               0 :     return mItems[aIndex].mItem;
     220                 :   }
     221                 : 
     222                 :   /**
     223                 :    * This struct is used in our array of mItems to provide us with somewhere to
     224                 :    * store the indexes into the internal SVGPathData of the internal seg data
     225                 :    * that our DOMSVGPathSeg items wrap (the internal segment data is or varying
     226                 :    * length, so we can't just use the index of our DOMSVGPathSeg items
     227                 :    * themselves). The reason that we have this separate struct rather than
     228                 :    * just storing the internal indexes in the DOMSVGPathSeg items is because we
     229                 :    * want to create the DOMSVGPathSeg items lazily on demand.
     230                 :    */
     231               0 :   struct ItemProxy {
     232               0 :     ItemProxy(){}
     233               0 :     ItemProxy(DOMSVGPathSeg *aItem, PRUint32 aInternalDataIndex)
     234                 :       : mItem(aItem)
     235               0 :       , mInternalDataIndex(aInternalDataIndex)
     236               0 :     {}
     237                 : 
     238                 :     DOMSVGPathSeg *mItem;
     239                 :     PRUint32 mInternalDataIndex;
     240                 :   };
     241                 : 
     242                 :   // Weak refs to our DOMSVGPathSeg items. The items are friends and take care
     243                 :   // of clearing our pointer to them when they die.
     244                 :   nsTArray<ItemProxy> mItems;
     245                 : 
     246                 :   // Strong ref to our element to keep it alive. We hold this not only for
     247                 :   // ourself, but also for our DOMSVGPathSeg items too.
     248                 :   nsRefPtr<nsSVGElement> mElement;
     249                 : 
     250                 :   bool mIsAnimValList;
     251                 : };
     252                 : 
     253                 : } // namespace mozilla
     254                 : 
     255                 : #endif // MOZILLA_DOMSVGPATHSEGLIST_H__

Generated by: LCOV version 1.7