Bumping manifests a=b2g-bump
[gecko.git] / dom / svg / DOMSVGNumberList.h
blob974b75b2a1f09aa6434ca4b5e7716a51b1c59f0e
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"
12 #include "nsDebug.h"
13 #include "nsTArray.h"
14 #include "SVGNumberList.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/ErrorResult.h"
18 class nsSVGElement;
20 namespace mozilla {
22 class DOMSVGNumber;
24 /**
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
37 * pointers to them.
39 * Our DOM items are created lazily on demand as and when script requests them.
41 class DOMSVGNumberList MOZ_FINAL : public nsISupports,
42 public nsWrapperCache
44 friend class AutoChangeNumberListNotifier;
45 friend class DOMSVGNumber;
47 ~DOMSVGNumberList() {
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.
51 if (mAList) {
52 ( IsAnimValList() ? mAList->mAnimVal : mAList->mBaseVal ) = nullptr;
56 public:
57 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
58 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGNumberList)
60 DOMSVGNumberList(DOMSVGAnimatedNumberList *aAList,
61 const SVGNumberList &aInternalList)
62 : mAList(aAList)
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());
79 /**
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);
93 /**
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,
110 ErrorResult& error);
111 already_AddRefed<DOMSVGNumber> GetItem(uint32_t index, ErrorResult& error);
112 already_AddRefed<DOMSVGNumber> IndexedGetter(uint32_t index, bool& found,
113 ErrorResult& error);
114 already_AddRefed<DOMSVGNumber> InsertItemBefore(DOMSVGNumber& newItem,
115 uint32_t index, ErrorResult& error);
116 already_AddRefed<DOMSVGNumber> ReplaceItem(DOMSVGNumber& newItem, uint32_t index,
117 ErrorResult& error);
118 already_AddRefed<DOMSVGNumber> RemoveItem(uint32_t index,
119 ErrorResult& error);
120 already_AddRefed<DOMSVGNumber> AppendItem(DOMSVGNumber& newItem,
121 ErrorResult& error)
123 return InsertItemBefore(newItem, LengthNoFlush(), error);
125 uint32_t Length() const
127 return NumberOfItems();
130 private:
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
153 * animVal lists.
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__