1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsSVGAttrTearoffTable.h"
10 #include "nsSVGElement.h"
11 #include "nsSMILValue.h"
12 #include "SMILEnumType.h"
14 using namespace mozilla
;
15 using namespace mozilla::dom
;
17 static nsSVGAttrTearoffTable
<nsSVGEnum
, nsSVGEnum::DOMAnimatedEnum
>
18 sSVGAnimatedEnumTearoffTable
;
21 nsSVGEnum::GetMapping(nsSVGElement
*aSVGElement
)
23 nsSVGElement::EnumAttributesInfo info
= aSVGElement
->GetEnumInfo();
25 NS_ASSERTION(info
.mEnumCount
> 0 && mAttrEnum
< info
.mEnumCount
,
26 "mapping request for a non-attrib enum");
28 return info
.mEnumInfo
[mAttrEnum
].mMapping
;
32 nsSVGEnum::SetBaseValueAtom(const nsIAtom
* aValue
, nsSVGElement
*aSVGElement
)
34 nsSVGEnumMapping
*mapping
= GetMapping(aSVGElement
);
36 while (mapping
&& mapping
->mKey
) {
37 if (aValue
== *(mapping
->mKey
)) {
39 if (mBaseVal
!= mapping
->mVal
) {
40 mBaseVal
= mapping
->mVal
;
45 aSVGElement
->AnimationNeedsResample();
47 // We don't need to call DidChange* here - we're only called by
48 // nsSVGElement::ParseAttribute under Element::SetAttr,
49 // which takes care of notifying.
56 // only a warning since authors may mistype attribute values
57 NS_WARNING("unknown enumeration key");
58 return NS_ERROR_DOM_SYNTAX_ERR
;
62 nsSVGEnum::GetBaseValueAtom(nsSVGElement
*aSVGElement
)
64 nsSVGEnumMapping
*mapping
= GetMapping(aSVGElement
);
66 while (mapping
&& mapping
->mKey
) {
67 if (mBaseVal
== mapping
->mVal
) {
68 return *mapping
->mKey
;
72 NS_ERROR("unknown enumeration value");
73 return nsGkAtoms::_empty
;
77 nsSVGEnum::SetBaseValue(uint16_t aValue
,
78 nsSVGElement
*aSVGElement
)
80 nsSVGEnumMapping
*mapping
= GetMapping(aSVGElement
);
82 while (mapping
&& mapping
->mKey
) {
83 if (mapping
->mVal
== aValue
) {
85 if (mBaseVal
!= uint8_t(aValue
)) {
86 mBaseVal
= uint8_t(aValue
);
91 aSVGElement
->AnimationNeedsResample();
93 aSVGElement
->DidChangeEnum(mAttrEnum
);
99 return NS_ERROR_DOM_SYNTAX_ERR
;
103 nsSVGEnum::SetAnimValue(uint16_t aValue
, nsSVGElement
*aSVGElement
)
105 if (mIsAnimated
&& aValue
== mAnimVal
) {
110 aSVGElement
->DidAnimateEnum(mAttrEnum
);
113 already_AddRefed
<SVGAnimatedEnumeration
>
114 nsSVGEnum::ToDOMAnimatedEnum(nsSVGElement
* aSVGElement
)
116 nsRefPtr
<DOMAnimatedEnum
> domAnimatedEnum
=
117 sSVGAnimatedEnumTearoffTable
.GetTearoff(this);
118 if (!domAnimatedEnum
) {
119 domAnimatedEnum
= new DOMAnimatedEnum(this, aSVGElement
);
120 sSVGAnimatedEnumTearoffTable
.AddTearoff(this, domAnimatedEnum
);
123 return domAnimatedEnum
.forget();
126 nsSVGEnum::DOMAnimatedEnum::~DOMAnimatedEnum()
128 sSVGAnimatedEnumTearoffTable
.RemoveTearoff(mVal
);
132 nsSVGEnum::ToSMILAttr(nsSVGElement
*aSVGElement
)
134 return new SMILEnum(this, aSVGElement
);
138 nsSVGEnum::SMILEnum::ValueFromString(const nsAString
& aStr
,
139 const dom::SVGAnimationElement
* /*aSrcElement*/,
141 bool& aPreventCachingOfSandwich
) const
143 nsIAtom
*valAtom
= NS_GetStaticAtom(aStr
);
145 nsSVGEnumMapping
*mapping
= mVal
->GetMapping(mSVGElement
);
147 while (mapping
&& mapping
->mKey
) {
148 if (valAtom
== *(mapping
->mKey
)) {
149 nsSMILValue
val(SMILEnumType::Singleton());
150 val
.mU
.mUint
= mapping
->mVal
;
152 aPreventCachingOfSandwich
= false;
159 // only a warning since authors may mistype attribute values
160 NS_WARNING("unknown enumeration key");
161 return NS_ERROR_FAILURE
;
165 nsSVGEnum::SMILEnum::GetBaseValue() const
167 nsSMILValue
val(SMILEnumType::Singleton());
168 val
.mU
.mUint
= mVal
->mBaseVal
;
173 nsSVGEnum::SMILEnum::ClearAnimValue()
175 if (mVal
->mIsAnimated
) {
176 mVal
->mIsAnimated
= false;
177 mVal
->mAnimVal
= mVal
->mBaseVal
;
178 mSVGElement
->DidAnimateEnum(mVal
->mAttrEnum
);
183 nsSVGEnum::SMILEnum::SetAnimValue(const nsSMILValue
& aValue
)
185 NS_ASSERTION(aValue
.mType
== SMILEnumType::Singleton(),
186 "Unexpected type to assign animated value");
187 if (aValue
.mType
== SMILEnumType::Singleton()) {
188 NS_ABORT_IF_FALSE(aValue
.mU
.mUint
<= USHRT_MAX
,
189 "Very large enumerated value - too big for uint16_t");
190 mVal
->SetAnimValue(uint16_t(aValue
.mU
.mUint
), mSVGElement
);