1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef MOZILLA_DOMSVGNUMBERLIST_H__
7 #define MOZILLA_DOMSVGNUMBERLIST_H__
9 #include "DOMSVGAnimatedNumberList.h"
10 #include "nsAutoPtr.h"
11 #include "nsCycleCollectionParticipant.h"
14 #include "SVGNumberList.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/ErrorResult.h"
25 * Class DOMSVGNumberList
27 * This class is used to create the DOM tearoff objects that wrap internal
28 * SVGNumberList objects.
30 * See the architecture comment in DOMSVGAnimatedNumberList.h.
32 * This class is strongly intertwined with DOMSVGAnimatedNumberList and
33 * DOMSVGNumber. We are a friend of DOMSVGAnimatedNumberList, and are
34 * responsible for nulling out our DOMSVGAnimatedNumberList's pointer to us
35 * when we die, essentially making its pointer to us a weak pointer. Similarly,
36 * our DOMSVGNumber items are friends of us and responsible for nulling out our
39 * Our DOM items are created lazily on demand as and when script requests them.
41 class DOMSVGNumberList MOZ_FINAL
: public nsISupports
,
44 friend class AutoChangeNumberListNotifier
;
45 friend class DOMSVGNumber
;
48 // Our mAList's weak ref to us must be nulled out when we die. If GC has
49 // unlinked us using the cycle collector code, then that has already
50 // happened, and mAList is null.
52 ( IsAnimValList() ? mAList
->mAnimVal
: mAList
->mBaseVal
) = nullptr;
57 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
58 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGNumberList
)
60 DOMSVGNumberList(DOMSVGAnimatedNumberList
*aAList
,
61 const SVGNumberList
&aInternalList
)
64 // aInternalList must be passed in explicitly because we can't use
65 // InternalList() here. (Because it depends on IsAnimValList, which depends
66 // on this object having been assigned to aAList's mBaseVal or mAnimVal,
67 // which hasn't happend yet.)
69 InternalListLengthWillChange(aInternalList
.Length()); // Sync mItems
72 virtual JSObject
* WrapObject(JSContext
*cx
) MOZ_OVERRIDE
;
74 nsISupports
* GetParentObject()
76 return static_cast<nsIContent
*>(Element());
80 * This will normally be the same as InternalList().Length(), except if we've
81 * hit OOM in which case our length will be zero.
83 uint32_t LengthNoFlush() const {
84 NS_ABORT_IF_FALSE(mItems
.Length() == 0 ||
85 mItems
.Length() == InternalList().Length(),
86 "DOM wrapper's list length is out of sync");
87 return mItems
.Length();
90 /// Called to notify us to syncronize our length and detach excess items.
91 void InternalListLengthWillChange(uint32_t aNewLength
);
94 * Returns true if our attribute is animating (in which case our animVal is
95 * not simply a mirror of our baseVal).
97 bool IsAnimating() const {
98 return mAList
->IsAnimating();
101 uint32_t NumberOfItems() const
103 if (IsAnimValList()) {
104 Element()->FlushAnimations();
106 return LengthNoFlush();
108 void Clear(ErrorResult
& error
);
109 already_AddRefed
<DOMSVGNumber
> Initialize(DOMSVGNumber
& newItem
,
111 already_AddRefed
<DOMSVGNumber
> GetItem(uint32_t index
, ErrorResult
& error
);
112 already_AddRefed
<DOMSVGNumber
> IndexedGetter(uint32_t index
, bool& found
,
114 already_AddRefed
<DOMSVGNumber
> InsertItemBefore(DOMSVGNumber
& newItem
,
115 uint32_t index
, ErrorResult
& error
);
116 already_AddRefed
<DOMSVGNumber
> ReplaceItem(DOMSVGNumber
& newItem
, uint32_t index
,
118 already_AddRefed
<DOMSVGNumber
> RemoveItem(uint32_t index
,
120 already_AddRefed
<DOMSVGNumber
> AppendItem(DOMSVGNumber
& newItem
,
123 return InsertItemBefore(newItem
, LengthNoFlush(), error
);
125 uint32_t Length() const
127 return NumberOfItems();
132 nsSVGElement
* Element() const {
133 return mAList
->mElement
;
136 uint8_t AttrEnum() const {
137 return mAList
->mAttrEnum
;
140 /// Used to determine if this list is the baseVal or animVal list.
141 bool IsAnimValList() const {
142 NS_ABORT_IF_FALSE(this == mAList
->mBaseVal
|| this == mAList
->mAnimVal
,
143 "Calling IsAnimValList() too early?!");
144 return this == mAList
->mAnimVal
;
148 * Get a reference to this object's corresponding internal SVGNumberList.
150 * To simplify the code we just have this one method for obtaining both
151 * baseVal and animVal internal lists. This means that animVal lists don't
152 * get const protection, but our setter methods guard against changing
155 SVGNumberList
& InternalList() const;
157 /// Returns the DOMSVGNumber at aIndex, creating it if necessary.
158 already_AddRefed
<DOMSVGNumber
> GetItemAt(uint32_t aIndex
);
160 void MaybeInsertNullInAnimValListAt(uint32_t aIndex
);
161 void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex
);
163 // Weak refs to our DOMSVGNumber items. The items are friends and take care
164 // of clearing our pointer to them when they die.
165 FallibleTArray
<DOMSVGNumber
*> mItems
;
167 nsRefPtr
<DOMSVGAnimatedNumberList
> mAList
;
170 } // namespace mozilla
172 #endif // MOZILLA_DOMSVGNUMBERLIST_H__