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_SVGANIMATEDPATHSEGLIST_H_
8 #define DOM_SVG_SVGANIMATEDPATHSEGLIST_H_
10 #include "mozilla/Attributes.h"
11 #include "mozilla/MemoryReporting.h"
12 #include "mozilla/SMILAttr.h"
13 #include "mozilla/UniquePtr.h"
14 #include "SVGPathData.h"
21 class SVGAnimationElement
;
26 * Class SVGAnimatedPathSegList
28 * Despite the fact that no SVGAnimatedPathSegList interface or objects exist
29 * in the SVG specification (unlike e.g. SVGAnimated*Length*List), we
30 * nevertheless have this internal class. (Note that there is an
31 * SVGAnimatedPathData interface, but that's quite different to
32 * SVGAnimatedLengthList since it is inherited by elements, as opposed to
33 * elements having members of that type.) The reason that we have this class is
34 * to provide a single locked down point of entry to the SVGPathData objects,
35 * which helps ensure that the DOM wrappers for SVGPathData objects' are always
36 * kept in sync. This is vitally important (see the comment in
37 * DOMSVGPathSegList::InternalListWillChangeTo) and frees consumers from having
38 * to know or worry about wrappers (or forget about them!) for the most part.
40 class SVGAnimatedPathSegList final
{
42 SVGAnimatedPathSegList() = default;
44 SVGAnimatedPathSegList
& operator=(const SVGAnimatedPathSegList
& aOther
) {
45 mBaseVal
= aOther
.mBaseVal
;
46 if (aOther
.mAnimVal
) {
47 mAnimVal
= MakeUnique
<SVGPathData
>(*aOther
.mAnimVal
);
53 * Because it's so important that mBaseVal and its DOMSVGPathSegList wrapper
54 * (if any) be kept in sync (see the comment in
55 * DOMSVGPathSegList::InternalListWillChangeTo), this method returns a const
56 * reference. Only our friend classes may get mutable references to mBaseVal.
58 const SVGPathData
& GetBaseValue() const { return mBaseVal
; }
60 nsresult
SetBaseValueString(const nsAString
& aValue
);
62 void ClearBaseValue();
65 * const! See comment for GetBaseValue!
67 const SVGPathData
& GetAnimValue() const {
68 return mAnimVal
? *mAnimVal
: mBaseVal
;
71 nsresult
SetAnimValue(const SVGPathData
& aNewAnimValue
,
72 dom::SVGElement
* aElement
);
74 void ClearAnimValue(dom::SVGElement
* aElement
);
77 * Empty paths are not rendered.
79 bool IsRendered() const;
82 * Needed for correct DOM wrapper construction since GetAnimValue may
83 * actually return the baseVal!
85 void* GetBaseValKey() const { return (void*)&mBaseVal
; }
86 void* GetAnimValKey() const { return (void*)&mAnimVal
; }
88 bool IsAnimating() const { return !!mAnimVal
; }
90 UniquePtr
<SMILAttr
> ToSMILAttr(dom::SVGElement
* aElement
);
92 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const;
95 // mAnimVal is a pointer to allow us to determine if we're being animated or
96 // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
97 // if we're animating is not an option, since that would break animation *to*
98 // the empty string (<set to="">).
100 SVGPathData mBaseVal
;
101 UniquePtr
<SVGPathData
> mAnimVal
;
103 struct SMILAnimatedPathSegList
: public SMILAttr
{
105 SMILAnimatedPathSegList(SVGAnimatedPathSegList
* aVal
,
106 dom::SVGElement
* aElement
)
107 : mVal(aVal
), mElement(aElement
) {}
109 // These will stay alive because a SMILAttr only lives as long
110 // as the Compositing step, and DOM elements don't get a chance to
112 SVGAnimatedPathSegList
* mVal
;
113 dom::SVGElement
* mElement
;
116 nsresult
ValueFromString(const nsAString
& aStr
,
117 const dom::SVGAnimationElement
* aSrcElement
,
119 bool& aPreventCachingOfSandwich
) const override
;
120 SMILValue
GetBaseValue() const override
;
121 void ClearAnimValue() override
;
122 nsresult
SetAnimValue(const SMILValue
& aValue
) override
;
126 } // namespace mozilla
128 #endif // DOM_SVG_SVGANIMATEDPATHSEGLIST_H_