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 #include "SVGAnimatedEnumeration.h"
9 #include "mozilla/dom/SVGElement.h"
10 #include "mozilla/SMILValue.h"
13 #include "SMILEnumType.h"
14 #include "SVGAttrTearoffTable.h"
16 using namespace mozilla::dom
;
20 static SVGAttrTearoffTable
<SVGAnimatedEnumeration
,
21 SVGAnimatedEnumeration::DOMAnimatedEnum
>
22 sSVGAnimatedEnumTearoffTable
;
24 const SVGEnumMapping
* SVGAnimatedEnumeration::GetMapping(
25 SVGElement
* aSVGElement
) {
26 SVGElement::EnumAttributesInfo info
= aSVGElement
->GetEnumInfo();
28 NS_ASSERTION(info
.mEnumCount
> 0 && mAttrEnum
< info
.mEnumCount
,
29 "mapping request for a non-attrib enum");
31 return info
.mEnumInfo
[mAttrEnum
].mMapping
;
34 bool SVGAnimatedEnumeration::SetBaseValueAtom(const nsAtom
* aValue
,
35 SVGElement
* aSVGElement
) {
36 const SVGEnumMapping
* mapping
= GetMapping(aSVGElement
);
38 while (mapping
&& mapping
->mKey
) {
39 if (aValue
== mapping
->mKey
) {
41 if (mBaseVal
!= mapping
->mVal
) {
42 mBaseVal
= mapping
->mVal
;
46 aSVGElement
->AnimationNeedsResample();
48 // We don't need to call DidChange* here - we're only called by
49 // SVGElement::ParseAttribute under Element::SetAttr,
50 // which takes care of notifying.
60 nsAtom
* SVGAnimatedEnumeration::GetBaseValueAtom(SVGElement
* aSVGElement
) {
61 const SVGEnumMapping
* mapping
= GetMapping(aSVGElement
);
63 while (mapping
&& mapping
->mKey
) {
64 if (mBaseVal
== mapping
->mVal
) {
69 NS_ERROR("unknown enumeration value");
70 return nsGkAtoms::_empty
;
73 void SVGAnimatedEnumeration::SetBaseValue(uint16_t aValue
,
74 SVGElement
* aSVGElement
,
76 const SVGEnumMapping
* mapping
= GetMapping(aSVGElement
);
78 while (mapping
&& mapping
->mKey
) {
79 if (mapping
->mVal
== aValue
) {
81 if (mBaseVal
!= uint8_t(aValue
)) {
82 mBaseVal
= uint8_t(aValue
);
86 aSVGElement
->AnimationNeedsResample();
88 aSVGElement
->DidChangeEnum(mAttrEnum
);
94 return aRv
.ThrowTypeError("Invalid SVGAnimatedEnumeration base value");
97 void SVGAnimatedEnumeration::SetAnimValue(uint16_t aValue
,
98 SVGElement
* aSVGElement
) {
99 if (mIsAnimated
&& aValue
== mAnimVal
) {
104 aSVGElement
->DidAnimateEnum(mAttrEnum
);
107 already_AddRefed
<DOMSVGAnimatedEnumeration
>
108 SVGAnimatedEnumeration::ToDOMAnimatedEnum(SVGElement
* aSVGElement
) {
109 RefPtr
<DOMAnimatedEnum
> domAnimatedEnum
=
110 sSVGAnimatedEnumTearoffTable
.GetTearoff(this);
111 if (!domAnimatedEnum
) {
112 domAnimatedEnum
= new DOMAnimatedEnum(this, aSVGElement
);
113 sSVGAnimatedEnumTearoffTable
.AddTearoff(this, domAnimatedEnum
);
116 return domAnimatedEnum
.forget();
119 SVGAnimatedEnumeration::DOMAnimatedEnum::~DOMAnimatedEnum() {
120 sSVGAnimatedEnumTearoffTable
.RemoveTearoff(mVal
);
123 UniquePtr
<SMILAttr
> SVGAnimatedEnumeration::ToSMILAttr(
124 SVGElement
* aSVGElement
) {
125 return MakeUnique
<SMILEnum
>(this, aSVGElement
);
128 nsresult
SVGAnimatedEnumeration::SMILEnum::ValueFromString(
129 const nsAString
& aStr
, const SVGAnimationElement
* /*aSrcElement*/,
130 SMILValue
& aValue
, bool& aPreventCachingOfSandwich
) const {
131 nsAtom
* valAtom
= NS_GetStaticAtom(aStr
);
133 const SVGEnumMapping
* mapping
= mVal
->GetMapping(mSVGElement
);
135 while (mapping
&& mapping
->mKey
) {
136 if (valAtom
== mapping
->mKey
) {
137 SMILValue
val(SMILEnumType::Singleton());
138 val
.mU
.mUint
= mapping
->mVal
;
140 aPreventCachingOfSandwich
= false;
147 // only a warning since authors may mistype attribute values
148 NS_WARNING("unknown enumeration key");
149 return NS_ERROR_FAILURE
;
152 SMILValue
SVGAnimatedEnumeration::SMILEnum::GetBaseValue() const {
153 SMILValue
val(SMILEnumType::Singleton());
154 val
.mU
.mUint
= mVal
->mBaseVal
;
158 void SVGAnimatedEnumeration::SMILEnum::ClearAnimValue() {
159 if (mVal
->mIsAnimated
) {
160 mVal
->mIsAnimated
= false;
161 mVal
->mAnimVal
= mVal
->mBaseVal
;
162 mSVGElement
->DidAnimateEnum(mVal
->mAttrEnum
);
166 nsresult
SVGAnimatedEnumeration::SMILEnum::SetAnimValue(
167 const SMILValue
& aValue
) {
168 NS_ASSERTION(aValue
.mType
== SMILEnumType::Singleton(),
169 "Unexpected type to assign animated value");
170 if (aValue
.mType
== SMILEnumType::Singleton()) {
171 MOZ_ASSERT(aValue
.mU
.mUint
<= USHRT_MAX
,
172 "Very large enumerated value - too big for uint16_t");
173 mVal
->SetAnimValue(uint16_t(aValue
.mU
.mUint
), mSVGElement
);
178 } // namespace mozilla