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_SVGANIMATEDTRANSFORMLIST_H_
8 #define DOM_SVG_SVGANIMATEDTRANSFORMLIST_H_
10 #include "mozilla/Attributes.h"
11 #include "mozilla/SMILAttr.h"
12 #include "mozilla/UniquePtr.h"
13 #include "mozilla/dom/SVGTransformList.h"
22 class SVGAnimationElement
;
24 class DOMSVGTransform
;
28 * Class SVGAnimatedTransformList
30 * This class is very different to the SVG DOM interface of the same name found
31 * in the SVG specification. This is a lightweight internal class - see
32 * DOMSVGAnimatedTransformList for the heavier DOM class that wraps instances of
33 * this class and implements the SVG specification's SVGAnimatedTransformList
36 * Except where noted otherwise, this class' methods take care of keeping the
37 * appropriate DOM wrappers in sync (see the comment in
38 * DOMSVGAnimatedTransformList::InternalBaseValListWillChangeTo) so that their
39 * consumers don't need to concern themselves with that.
41 class SVGAnimatedTransformList
{
42 // friends so that they can get write access to mBaseVal
43 friend class dom::DOMSVGTransform
;
44 friend class dom::DOMSVGTransformList
;
47 SVGAnimatedTransformList()
48 : mIsBaseSet(false), mCreatedOrRemovedOnLastChange(true) {}
50 SVGAnimatedTransformList
& operator=(const SVGAnimatedTransformList
& aOther
) {
51 mBaseVal
= aOther
.mBaseVal
;
52 if (aOther
.mAnimVal
) {
53 mAnimVal
= MakeUnique
<SVGTransformList
>(*aOther
.mAnimVal
);
55 mIsBaseSet
= aOther
.mIsBaseSet
;
56 mCreatedOrRemovedOnLastChange
= aOther
.mCreatedOrRemovedOnLastChange
;
61 * Because it's so important that mBaseVal and its DOMSVGTransformList wrapper
62 * (if any) be kept in sync (see the comment in
63 * DOMSVGAnimatedTransformList::InternalBaseValListWillChangeTo), this method
64 * returns a const reference. Only our friend classes may get mutable
65 * references to mBaseVal.
67 const SVGTransformList
& GetBaseValue() const { return mBaseVal
; }
69 nsresult
SetBaseValue(const SVGTransformList
& aValue
,
70 dom::SVGElement
* aSVGElement
);
72 nsresult
SetBaseValueString(const nsAString
& aValue
,
73 dom::SVGElement
* aSVGElement
);
75 void ClearBaseValue();
77 const SVGTransformList
& GetAnimValue() const {
78 return mAnimVal
? *mAnimVal
: mBaseVal
;
81 nsresult
SetAnimValue(const SVGTransformList
& aValue
,
82 dom::SVGElement
* aElement
);
84 void ClearAnimValue(dom::SVGElement
* aElement
);
87 * Returns true if the corresponding transform attribute is set (or animated)
88 * to a valid value. Unlike HasTransform it will return true for an empty
91 bool IsExplicitlySet() const;
94 * Returns true if the corresponding transform attribute is set (or animated)
95 * to a valid value, such that we have at least one transform in our list.
96 * Returns false otherwise (e.g. if the transform attribute is missing or
99 bool HasTransform() const {
100 return (mAnimVal
&& !mAnimVal
->IsEmpty()) || !mBaseVal
.IsEmpty();
103 bool IsAnimating() const { return !!mAnimVal
; }
106 * Returns true if the last change of this transform went from having to not
107 * having a transform or vice versa.
109 * (This is used as part of an optimization in
110 * SVGTransformableElement::GetAttributeChangeHint. That function reports an
111 * inexpensive nsChangeHint when a transform has just modified -- but this
112 * accessor lets it detect cases where the "modification" is actually creating
113 * a transform where we previously had none. These cases require a more
114 * thorough nsChangeHint.)
116 bool CreatedOrRemovedOnLastChange() const {
117 return mCreatedOrRemovedOnLastChange
;
120 UniquePtr
<SMILAttr
> ToSMILAttr(dom::SVGElement
* aSVGElement
);
123 // mAnimVal is a pointer to allow us to determine if we're being animated or
124 // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
125 // if we're animating is not an option, since that would break animation *to*
126 // the empty string (<set to="">).
128 SVGTransformList mBaseVal
;
129 UniquePtr
<SVGTransformList
> mAnimVal
;
131 // See documentation for accessor.
132 bool mCreatedOrRemovedOnLastChange
;
134 struct SMILAnimatedTransformList
: public SMILAttr
{
136 SMILAnimatedTransformList(SVGAnimatedTransformList
* aVal
,
137 dom::SVGElement
* aSVGElement
)
138 : mVal(aVal
), mElement(aSVGElement
) {}
141 nsresult
ValueFromString(const nsAString
& aStr
,
142 const dom::SVGAnimationElement
* aSrcElement
,
144 bool& aPreventCachingOfSandwich
) const override
;
145 SMILValue
GetBaseValue() const override
;
146 void ClearAnimValue() override
;
147 nsresult
SetAnimValue(const SMILValue
& aNewAnimValue
) override
;
150 static void ParseValue(const nsAString
& aSpec
, const nsAtom
* aTransformType
,
152 static int32_t ParseParameterList(const nsAString
& aSpec
, float* aVars
,
155 // These will stay alive because a SMILAttr only lives as long
156 // as the Compositing step, and DOM elements don't get a chance to
158 SVGAnimatedTransformList
* mVal
;
159 dom::SVGElement
* mElement
;
163 } // namespace mozilla
165 #endif // DOM_SVG_SVGANIMATEDTRANSFORMLIST_H_