1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DOM_SVG_SVGNUMBERLIST_H_
8 #define DOM_SVG_SVGNUMBERLIST_H_
12 #include "nsIContent.h"
14 #include "nsIWeakReferenceUtils.h"
15 #include "SVGElement.h"
22 class DOMSVGNumberList
;
26 * ATTENTION! WARNING! WATCH OUT!!
28 * Consumers that modify objects of this type absolutely MUST keep the DOM
29 * wrappers for those lists (if any) in sync!! That's why this class is so
32 * The DOM wrapper class for this class is DOMSVGNumberList.
35 friend class dom::DOMSVGNumber
;
36 friend class dom::DOMSVGNumberList
;
37 friend class SVGAnimatedNumberList
;
40 SVGNumberList() = default;
41 ~SVGNumberList() = default;
43 SVGNumberList
& operator=(const SVGNumberList
& aOther
) {
44 mNumbers
.ClearAndRetainStorage();
45 // Best-effort, really.
46 Unused
<< mNumbers
.AppendElements(aOther
.mNumbers
, fallible
);
50 SVGNumberList(const SVGNumberList
& aOther
) { *this = aOther
; }
52 // Only methods that don't make/permit modification to this list are public.
53 // Only our friend classes can access methods that may change us.
55 /// This may return an incomplete string on OOM, but that's acceptable.
56 void GetValueAsString(nsAString
& aValue
) const;
58 bool IsEmpty() const { return mNumbers
.IsEmpty(); }
60 uint32_t Length() const { return mNumbers
.Length(); }
62 const float& operator[](uint32_t aIndex
) const { return mNumbers
[aIndex
]; }
64 bool operator==(const SVGNumberList
& rhs
) const {
65 return mNumbers
== rhs
.mNumbers
;
68 bool SetCapacity(uint32_t size
) {
69 return mNumbers
.SetCapacity(size
, fallible
);
72 void Compact() { mNumbers
.Compact(); }
74 // Access to methods that can modify objects of this type is deliberately
75 // limited. This is to reduce the chances of someone modifying objects of
76 // this type without taking the necessary steps to keep DOM wrappers in sync.
77 // If you need wider access to these methods, consider adding a method to
78 // SVGAnimatedNumberList and having that class act as an intermediary so it
79 // can take care of keeping DOM wrappers in sync.
83 * This may fail on OOM if the internal capacity needs to be increased, in
84 * which case the list will be left unmodified.
86 nsresult
CopyFrom(const SVGNumberList
& rhs
);
87 void SwapWith(SVGNumberList
& aRhs
) { mNumbers
.SwapElements(aRhs
.mNumbers
); }
89 float& operator[](uint32_t aIndex
) { return mNumbers
[aIndex
]; }
92 * This may fail (return false) on OOM if the internal capacity is being
93 * increased, in which case the list will be left unmodified.
95 bool SetLength(uint32_t aNumberOfItems
) {
96 return mNumbers
.SetLength(aNumberOfItems
, fallible
);
100 // Marking the following private only serves to show which methods are only
101 // used by our friend classes (as opposed to our subclasses) - it doesn't
102 // really provide additional safety.
104 nsresult
SetValueFromString(const nsAString
& aValue
);
106 void Clear() { mNumbers
.Clear(); }
108 bool InsertItem(uint32_t aIndex
, const float& aNumber
) {
109 if (aIndex
>= mNumbers
.Length()) {
110 aIndex
= mNumbers
.Length();
112 return !!mNumbers
.InsertElementAt(aIndex
, aNumber
, fallible
);
115 void ReplaceItem(uint32_t aIndex
, const float& aNumber
) {
116 MOZ_ASSERT(aIndex
< mNumbers
.Length(),
117 "DOM wrapper caller should have raised INDEX_SIZE_ERR");
118 mNumbers
[aIndex
] = aNumber
;
121 void RemoveItem(uint32_t aIndex
) {
122 MOZ_ASSERT(aIndex
< mNumbers
.Length(),
123 "DOM wrapper caller should have raised INDEX_SIZE_ERR");
124 mNumbers
.RemoveElementAt(aIndex
);
127 bool AppendItem(float aNumber
) {
128 return !!mNumbers
.AppendElement(aNumber
, fallible
);
132 /* See SVGLengthList for the rationale for using FallibleTArray<float> instead
133 * of FallibleTArray<float, 1>.
135 FallibleTArray
<float> mNumbers
;
139 * This SVGNumberList subclass is used by the SMIL code when a number list
140 * is to be stored in a SMILValue instance. Since SMILValue objects may
141 * be cached, it is necessary for us to hold a strong reference to our element
142 * so that it doesn't disappear out from under us if, say, the element is
143 * removed from the DOM tree.
145 class SVGNumberListAndInfo
: public SVGNumberList
{
147 SVGNumberListAndInfo() : mElement(nullptr) {}
149 explicit SVGNumberListAndInfo(dom::SVGElement
* aElement
)
150 : mElement(do_GetWeakReference(static_cast<nsINode
*>(aElement
))) {}
152 void SetInfo(dom::SVGElement
* aElement
) {
153 mElement
= do_GetWeakReference(static_cast<nsINode
*>(aElement
));
156 dom::SVGElement
* Element() const {
157 nsCOMPtr
<nsIContent
> e
= do_QueryReferent(mElement
);
158 return static_cast<dom::SVGElement
*>(e
.get());
161 nsresult
CopyFrom(const SVGNumberListAndInfo
& rhs
) {
162 mElement
= rhs
.mElement
;
163 return SVGNumberList::CopyFrom(rhs
);
166 // Instances of this special subclass do not have DOM wrappers that we need
167 // to worry about keeping in sync, so it's safe to expose any hidden base
168 // class methods required by the SMIL code, as we do below.
171 * Exposed so that SVGNumberList baseVals can be copied to
172 * SVGNumberListAndInfo objects. Note that callers should also call
173 * SetInfo() when using this method!
175 nsresult
CopyFrom(const SVGNumberList
& rhs
) {
176 return SVGNumberList::CopyFrom(rhs
);
178 const float& operator[](uint32_t aIndex
) const {
179 return SVGNumberList::operator[](aIndex
);
181 float& operator[](uint32_t aIndex
) {
182 return SVGNumberList::operator[](aIndex
);
184 bool SetLength(uint32_t aNumberOfItems
) {
185 return SVGNumberList::SetLength(aNumberOfItems
);
189 // We must keep a weak reference to our element because we may belong to a
190 // cached baseVal SMILValue. See the comments starting at:
191 // https://bugzilla.mozilla.org/show_bug.cgi?id=515116#c15
192 // See also https://bugzilla.mozilla.org/show_bug.cgi?id=653497
196 } // namespace mozilla
198 #endif // DOM_SVG_SVGNUMBERLIST_H_