Backed out 4 changesets (bug 1825722) for causing reftest failures CLOSED TREE
[gecko.git] / dom / svg / SVGAnimatedTransformList.h
blob7cac5c0dfdfca59c77ea26297fafc3f4e98f075c
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"
15 class nsAtom;
17 namespace mozilla {
19 class SMILValue;
21 namespace dom {
22 class SVGAnimationElement;
23 class SVGElement;
24 class DOMSVGTransform;
25 } // namespace dom
27 /**
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
34 * DOM interface.
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;
46 public:
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;
57 return *this;
60 /**
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);
86 /**
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
89 * transform.
91 bool IsExplicitlySet() const;
93 /**
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
97 * empty or invalid).
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);
122 private:
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;
130 bool mIsBaseSet;
131 // See documentation for accessor.
132 bool mCreatedOrRemovedOnLastChange;
134 struct SMILAnimatedTransformList : public SMILAttr {
135 public:
136 SMILAnimatedTransformList(SVGAnimatedTransformList* aVal,
137 dom::SVGElement* aSVGElement)
138 : mVal(aVal), mElement(aSVGElement) {}
140 // SMILAttr methods
141 nsresult ValueFromString(const nsAString& aStr,
142 const dom::SVGAnimationElement* aSrcElement,
143 SMILValue& aValue,
144 bool& aPreventCachingOfSandwich) const override;
145 SMILValue GetBaseValue() const override;
146 void ClearAnimValue() override;
147 nsresult SetAnimValue(const SMILValue& aNewAnimValue) override;
149 protected:
150 static void ParseValue(const nsAString& aSpec, const nsAtom* aTransformType,
151 SMILValue& aResult);
152 static int32_t ParseParameterList(const nsAString& aSpec, float* aVars,
153 int32_t aNVars);
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
157 // die during that.
158 SVGAnimatedTransformList* mVal;
159 dom::SVGElement* mElement;
163 } // namespace mozilla
165 #endif // DOM_SVG_SVGANIMATEDTRANSFORMLIST_H_