Line data Source code
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/. */
6 :
7 : #include "nsError.h"
8 : #include "nsSVGAttrTearoffTable.h"
9 : #include "nsSVGBoolean.h"
10 : #include "nsSMILValue.h"
11 : #include "SMILBoolType.h"
12 : #include "SVGAnimatedBoolean.h"
13 :
14 : using namespace mozilla;
15 : using namespace mozilla::dom;
16 :
17 : /* Implementation */
18 :
19 : static inline
20 : nsSVGAttrTearoffTable<nsSVGBoolean, SVGAnimatedBoolean>&
21 0 : SVGAnimatedBooleanTearoffTable()
22 : {
23 : static nsSVGAttrTearoffTable<nsSVGBoolean, SVGAnimatedBoolean>
24 0 : sSVGAnimatedBooleanTearoffTable;
25 0 : return sSVGAnimatedBooleanTearoffTable;
26 : }
27 :
28 : static bool
29 0 : GetValueFromString(const nsAString& aValueAsString,
30 : bool& aValue)
31 : {
32 0 : if (aValueAsString.EqualsLiteral("true")) {
33 0 : aValue = true;
34 0 : return true;
35 : }
36 0 : if (aValueAsString.EqualsLiteral("false")) {
37 0 : aValue = false;
38 0 : return true;
39 : }
40 0 : return false;
41 : }
42 :
43 : static nsresult
44 0 : GetValueFromAtom(const nsIAtom* aValueAsAtom, bool *aValue)
45 : {
46 0 : if (aValueAsAtom == nsGkAtoms::_true) {
47 0 : *aValue = true;
48 0 : return NS_OK;
49 : }
50 0 : if (aValueAsAtom == nsGkAtoms::_false) {
51 0 : *aValue = false;
52 0 : return NS_OK;
53 : }
54 0 : return NS_ERROR_DOM_SYNTAX_ERR;
55 : }
56 :
57 : nsresult
58 0 : nsSVGBoolean::SetBaseValueAtom(const nsIAtom* aValue, nsSVGElement *aSVGElement)
59 : {
60 0 : bool val = false;
61 :
62 0 : nsresult rv = GetValueFromAtom(aValue, &val);
63 0 : if (NS_FAILED(rv)) {
64 0 : return rv;
65 : }
66 :
67 0 : mBaseVal = val;
68 0 : if (!mIsAnimated) {
69 0 : mAnimVal = mBaseVal;
70 : }
71 : else {
72 0 : aSVGElement->AnimationNeedsResample();
73 : }
74 :
75 : // We don't need to call DidChange* here - we're only called by
76 : // nsSVGElement::ParseAttribute under Element::SetAttr,
77 : // which takes care of notifying.
78 0 : return NS_OK;
79 : }
80 :
81 : nsIAtom*
82 0 : nsSVGBoolean::GetBaseValueAtom() const
83 : {
84 0 : return mBaseVal ? nsGkAtoms::_true : nsGkAtoms::_false;
85 : }
86 :
87 : void
88 0 : nsSVGBoolean::SetBaseValue(bool aValue, nsSVGElement *aSVGElement)
89 : {
90 0 : if (aValue == mBaseVal) {
91 0 : return;
92 : }
93 :
94 0 : mBaseVal = aValue;
95 0 : if (!mIsAnimated) {
96 0 : mAnimVal = mBaseVal;
97 : } else {
98 0 : aSVGElement->AnimationNeedsResample();
99 : }
100 0 : aSVGElement->DidChangeBoolean(mAttrEnum);
101 : }
102 :
103 : void
104 0 : nsSVGBoolean::SetAnimValue(bool aValue, nsSVGElement *aSVGElement)
105 : {
106 0 : if (mIsAnimated && mAnimVal == aValue) {
107 0 : return;
108 : }
109 0 : mAnimVal = aValue;
110 0 : mIsAnimated = true;
111 0 : aSVGElement->DidAnimateBoolean(mAttrEnum);
112 : }
113 :
114 : already_AddRefed<SVGAnimatedBoolean>
115 0 : nsSVGBoolean::ToDOMAnimatedBoolean(nsSVGElement* aSVGElement)
116 : {
117 : RefPtr<SVGAnimatedBoolean> domAnimatedBoolean =
118 0 : SVGAnimatedBooleanTearoffTable().GetTearoff(this);
119 0 : if (!domAnimatedBoolean) {
120 0 : domAnimatedBoolean = new SVGAnimatedBoolean(this, aSVGElement);
121 0 : SVGAnimatedBooleanTearoffTable().AddTearoff(this, domAnimatedBoolean);
122 : }
123 :
124 0 : return domAnimatedBoolean.forget();
125 : }
126 :
127 0 : SVGAnimatedBoolean::~SVGAnimatedBoolean()
128 : {
129 0 : SVGAnimatedBooleanTearoffTable().RemoveTearoff(mVal);
130 0 : }
131 :
132 : UniquePtr<nsISMILAttr>
133 0 : nsSVGBoolean::ToSMILAttr(nsSVGElement *aSVGElement)
134 : {
135 0 : return MakeUnique<SMILBool>(this, aSVGElement);
136 : }
137 :
138 : nsresult
139 0 : nsSVGBoolean::SMILBool::ValueFromString(const nsAString& aStr,
140 : const SVGAnimationElement* /*aSrcElement*/,
141 : nsSMILValue& aValue,
142 : bool& aPreventCachingOfSandwich) const
143 : {
144 : bool value;
145 0 : if (!GetValueFromString(aStr, value)) {
146 0 : return NS_ERROR_DOM_SYNTAX_ERR;
147 : }
148 :
149 0 : nsSMILValue val(SMILBoolType::Singleton());
150 0 : val.mU.mBool = value;
151 0 : aValue = val;
152 0 : aPreventCachingOfSandwich = false;
153 :
154 0 : return NS_OK;
155 : }
156 :
157 : nsSMILValue
158 0 : nsSVGBoolean::SMILBool::GetBaseValue() const
159 : {
160 0 : nsSMILValue val(SMILBoolType::Singleton());
161 0 : val.mU.mBool = mVal->mBaseVal;
162 0 : return val;
163 : }
164 :
165 : void
166 0 : nsSVGBoolean::SMILBool::ClearAnimValue()
167 : {
168 0 : if (mVal->mIsAnimated) {
169 0 : mVal->mIsAnimated = false;
170 0 : mVal->mAnimVal = mVal->mBaseVal;
171 0 : mSVGElement->DidAnimateBoolean(mVal->mAttrEnum);
172 : }
173 0 : }
174 :
175 : nsresult
176 0 : nsSVGBoolean::SMILBool::SetAnimValue(const nsSMILValue& aValue)
177 : {
178 0 : NS_ASSERTION(aValue.mType == SMILBoolType::Singleton(),
179 : "Unexpected type to assign animated value");
180 0 : if (aValue.mType == SMILBoolType::Singleton()) {
181 0 : mVal->SetAnimValue(uint16_t(aValue.mU.mBool), mSVGElement);
182 : }
183 0 : return NS_OK;
184 : }
|