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_SVGPOINTLIST_H_
8 #define DOM_SVG_SVGPOINTLIST_H_
12 #include "nsIContent.h"
14 #include "nsIWeakReferenceUtils.h"
15 #include "SVGElement.h"
25 class DOMSVGPointList
;
29 * ATTENTION! WARNING! WATCH OUT!!
31 * Consumers that modify objects of this type absolutely MUST keep the DOM
32 * wrappers for those lists (if any) in sync!! That's why this class is so
35 * The DOM wrapper class for this class is DOMSVGPointList.
38 friend class SVGAnimatedPointList
;
39 friend class dom::DOMSVGPointList
;
40 friend class dom::DOMSVGPoint
;
43 SVGPointList() = default;
44 ~SVGPointList() = default;
46 SVGPointList
& operator=(const SVGPointList
& aOther
) {
47 mItems
.ClearAndRetainStorage();
48 // Best-effort, really.
49 Unused
<< mItems
.AppendElements(aOther
.mItems
, fallible
);
53 SVGPointList(const SVGPointList
& aOther
) { *this = aOther
; }
55 // Only methods that don't make/permit modification to this list are public.
56 // Only our friend classes can access methods that may change us.
58 /// This may return an incomplete string on OOM, but that's acceptable.
59 void GetValueAsString(nsAString
& aValue
) const;
61 bool IsEmpty() const { return mItems
.IsEmpty(); }
63 uint32_t Length() const { return mItems
.Length(); }
65 const SVGPoint
& operator[](uint32_t aIndex
) const { return mItems
[aIndex
]; }
67 bool operator==(const SVGPointList
& rhs
) const {
68 // memcmp can be faster than |mItems == rhs.mItems|
69 return mItems
.Length() == rhs
.mItems
.Length() &&
70 memcmp(mItems
.Elements(), rhs
.mItems
.Elements(),
71 mItems
.Length() * sizeof(SVGPoint
)) == 0;
74 bool SetCapacity(uint32_t aSize
) {
75 return mItems
.SetCapacity(aSize
, fallible
);
78 void Compact() { mItems
.Compact(); }
80 // Access to methods that can modify objects of this type is deliberately
81 // limited. This is to reduce the chances of someone modifying objects of
82 // this type without taking the necessary steps to keep DOM wrappers in sync.
83 // If you need wider access to these methods, consider adding a method to
84 // SVGAnimatedPointList and having that class act as an intermediary so it
85 // can take care of keeping DOM wrappers in sync.
89 * This may fail on OOM if the internal capacity needs to be increased, in
90 * which case the list will be left unmodified.
92 nsresult
CopyFrom(const SVGPointList
& rhs
);
93 void SwapWith(SVGPointList
& aRhs
) { mItems
.SwapElements(aRhs
.mItems
); }
95 SVGPoint
& operator[](uint32_t aIndex
) { return mItems
[aIndex
]; }
98 * This may fail (return false) on OOM if the internal capacity is being
99 * increased, in which case the list will be left unmodified.
101 bool SetLength(uint32_t aNumberOfItems
) {
102 return mItems
.SetLength(aNumberOfItems
, fallible
);
106 // Marking the following private only serves to show which methods are only
107 // used by our friend classes (as opposed to our subclasses) - it doesn't
108 // really provide additional safety.
110 nsresult
SetValueFromString(const nsAString
& aValue
);
112 void Clear() { mItems
.Clear(); }
114 bool InsertItem(uint32_t aIndex
, const SVGPoint
& aPoint
) {
115 if (aIndex
>= mItems
.Length()) {
116 aIndex
= mItems
.Length();
118 return !!mItems
.InsertElementAt(aIndex
, aPoint
, fallible
);
121 void ReplaceItem(uint32_t aIndex
, const SVGPoint
& aPoint
) {
122 MOZ_ASSERT(aIndex
< mItems
.Length(),
123 "DOM wrapper caller should have raised INDEX_SIZE_ERR");
124 mItems
[aIndex
] = aPoint
;
127 void RemoveItem(uint32_t aIndex
) {
128 MOZ_ASSERT(aIndex
< mItems
.Length(),
129 "DOM wrapper caller should have raised INDEX_SIZE_ERR");
130 mItems
.RemoveElementAt(aIndex
);
133 bool AppendItem(SVGPoint aPoint
) {
134 return !!mItems
.AppendElement(aPoint
, fallible
);
138 /* See SVGLengthList for the rationale for using FallibleTArray<SVGPoint>
139 * instead of FallibleTArray<SVGPoint, 1>.
141 FallibleTArray
<SVGPoint
> mItems
;
145 * This SVGPointList subclass is for SVGPointListSMILType which needs a
146 * mutable version of SVGPointList. Instances of this class do not have
147 * DOM wrappers that need to be kept in sync, so we can safely expose any
148 * protected base class methods required by the SMIL code.
150 * This class contains a strong reference to the element that instances of
151 * this class are being used to animate. This is because the SMIL code stores
152 * instances of this class in SMILValue objects, some of which are cached.
153 * Holding a strong reference to the element here prevents the element from
154 * disappearing out from under the SMIL code unexpectedly.
156 class SVGPointListAndInfo
: public SVGPointList
{
158 explicit SVGPointListAndInfo(dom::SVGElement
* aElement
= nullptr)
159 : mElement(do_GetWeakReference(static_cast<nsINode
*>(aElement
))) {}
161 void SetInfo(dom::SVGElement
* aElement
) {
162 mElement
= do_GetWeakReference(static_cast<nsINode
*>(aElement
));
165 dom::SVGElement
* Element() const {
166 nsCOMPtr
<nsIContent
> e
= do_QueryReferent(mElement
);
167 return static_cast<dom::SVGElement
*>(e
.get());
171 * Returns true if this object is an "identity" value, from the perspective
172 * of SMIL. In other words, returns true until the initial value set up in
173 * SVGPointListSMILType::Init() has been changed with a SetInfo() call.
175 bool IsIdentity() const {
177 MOZ_ASSERT(IsEmpty(), "target element propagation failure");
183 nsresult
CopyFrom(const SVGPointListAndInfo
& rhs
) {
184 mElement
= rhs
.mElement
;
185 return SVGPointList::CopyFrom(rhs
);
189 * Exposed so that SVGPointList baseVals can be copied to
190 * SVGPointListAndInfo objects. Note that callers should also call
191 * SetElement() when using this method!
193 nsresult
CopyFrom(const SVGPointList
& rhs
) {
194 return SVGPointList::CopyFrom(rhs
);
196 const SVGPoint
& operator[](uint32_t aIndex
) const {
197 return SVGPointList::operator[](aIndex
);
199 SVGPoint
& operator[](uint32_t aIndex
) {
200 return SVGPointList::operator[](aIndex
);
202 bool SetLength(uint32_t aNumberOfItems
) {
203 return SVGPointList::SetLength(aNumberOfItems
);
207 // We must keep a weak reference to our element because we may belong to a
208 // cached baseVal SMILValue. See the comments starting at:
209 // https://bugzilla.mozilla.org/show_bug.cgi?id=515116#c15
210 // See also https://bugzilla.mozilla.org/show_bug.cgi?id=653497
214 } // namespace mozilla
216 #endif // DOM_SVG_SVGPOINTLIST_H_