Backed out 2 changesets (bug 1926630) for causing macOS assertion failures. CLOSED...
[gecko.git] / dom / svg / SVGAnimatedBoolean.cpp
blobdf675759d9144a0c6662fc42922daf78f0ad7709
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 "SVGAnimatedBoolean.h"
9 #include "DOMSVGAnimatedBoolean.h"
10 #include "nsError.h"
11 #include "SMILBoolType.h"
12 #include "SVGAttrTearoffTable.h"
13 #include "mozilla/SMILValue.h"
15 using namespace mozilla::dom;
17 namespace mozilla {
19 /* Implementation */
21 //----------------------------------------------------------------------
22 // Helper class: AutoChangeBooleanNotifier
23 // Stack-based helper class to ensure DidChangeBoolean is called.
24 class MOZ_RAII AutoChangeBooleanNotifier {
25 public:
26 AutoChangeBooleanNotifier(SVGAnimatedBoolean* aBoolean,
27 SVGElement* aSVGElement, bool aDoSetAttr = true)
28 : mBoolean(aBoolean), mSVGElement(aSVGElement), mDoSetAttr(aDoSetAttr) {
29 MOZ_ASSERT(mBoolean, "Expecting non-null boolean");
30 MOZ_ASSERT(mSVGElement, "Expecting non-null element");
33 ~AutoChangeBooleanNotifier() {
34 if (mDoSetAttr) {
35 mSVGElement->DidChangeBoolean(mBoolean->mAttrEnum);
37 if (mBoolean->mIsAnimated) {
38 mSVGElement->AnimationNeedsResample();
42 private:
43 SVGAnimatedBoolean* const mBoolean;
44 SVGElement* const mSVGElement;
45 bool mDoSetAttr;
48 static inline SVGAttrTearoffTable<SVGAnimatedBoolean, DOMSVGAnimatedBoolean>&
49 SVGAnimatedBooleanTearoffTable() {
50 static SVGAttrTearoffTable<SVGAnimatedBoolean, DOMSVGAnimatedBoolean>
51 sSVGAnimatedBooleanTearoffTable;
52 return sSVGAnimatedBooleanTearoffTable;
55 static bool GetValueFromString(const nsAString& aValueAsString, bool& aValue) {
56 if (aValueAsString.EqualsLiteral("true")) {
57 aValue = true;
58 return true;
60 if (aValueAsString.EqualsLiteral("false")) {
61 aValue = false;
62 return true;
64 return false;
67 static nsresult GetValueFromAtom(const nsAtom* aValueAsAtom, bool* aValue) {
68 if (aValueAsAtom == nsGkAtoms::_true) {
69 *aValue = true;
70 return NS_OK;
72 if (aValueAsAtom == nsGkAtoms::_false) {
73 *aValue = false;
74 return NS_OK;
76 return NS_ERROR_DOM_SYNTAX_ERR;
79 nsresult SVGAnimatedBoolean::SetBaseValueAtom(const nsAtom* aValue,
80 SVGElement* aSVGElement) {
81 bool val = false;
83 nsresult rv = GetValueFromAtom(aValue, &val);
84 if (NS_FAILED(rv)) {
85 return rv;
88 // We don't need to call DidChange* here - we're only called by
89 // SVGElement::ParseAttribute under Element::SetAttr,
90 // which takes care of notifying.
91 AutoChangeBooleanNotifier notifier(this, aSVGElement, false);
93 mBaseVal = val;
94 if (!mIsAnimated) {
95 mAnimVal = mBaseVal;
98 return NS_OK;
101 nsAtom* SVGAnimatedBoolean::GetBaseValueAtom() const {
102 return mBaseVal ? nsGkAtoms::_true : nsGkAtoms::_false;
105 void SVGAnimatedBoolean::SetBaseValue(bool aValue, SVGElement* aSVGElement) {
106 if (aValue == mBaseVal) {
107 return;
110 AutoChangeBooleanNotifier notifier(this, aSVGElement);
112 mBaseVal = aValue;
113 if (!mIsAnimated) {
114 mAnimVal = mBaseVal;
118 void SVGAnimatedBoolean::SetAnimValue(bool aValue, SVGElement* aSVGElement) {
119 if (mIsAnimated && mAnimVal == aValue) {
120 return;
122 mAnimVal = aValue;
123 mIsAnimated = true;
124 aSVGElement->DidAnimateBoolean(mAttrEnum);
127 already_AddRefed<DOMSVGAnimatedBoolean>
128 SVGAnimatedBoolean::ToDOMAnimatedBoolean(SVGElement* aSVGElement) {
129 RefPtr<DOMSVGAnimatedBoolean> domAnimatedBoolean =
130 SVGAnimatedBooleanTearoffTable().GetTearoff(this);
131 if (!domAnimatedBoolean) {
132 domAnimatedBoolean = new DOMSVGAnimatedBoolean(this, aSVGElement);
133 SVGAnimatedBooleanTearoffTable().AddTearoff(this, domAnimatedBoolean);
136 return domAnimatedBoolean.forget();
139 DOMSVGAnimatedBoolean::~DOMSVGAnimatedBoolean() {
140 SVGAnimatedBooleanTearoffTable().RemoveTearoff(mVal);
143 UniquePtr<SMILAttr> SVGAnimatedBoolean::ToSMILAttr(SVGElement* aSVGElement) {
144 return MakeUnique<SMILBool>(this, aSVGElement);
147 nsresult SVGAnimatedBoolean::SMILBool::ValueFromString(
148 const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
149 SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
150 bool value;
151 if (!GetValueFromString(aStr, value)) {
152 return NS_ERROR_DOM_SYNTAX_ERR;
155 SMILValue val(SMILBoolType::Singleton());
156 val.mU.mBool = value;
157 aValue = val;
159 return NS_OK;
162 SMILValue SVGAnimatedBoolean::SMILBool::GetBaseValue() const {
163 SMILValue val(SMILBoolType::Singleton());
164 val.mU.mBool = mVal->mBaseVal;
165 return val;
168 void SVGAnimatedBoolean::SMILBool::ClearAnimValue() {
169 if (mVal->mIsAnimated) {
170 mVal->mIsAnimated = false;
171 mVal->mAnimVal = mVal->mBaseVal;
172 mSVGElement->DidAnimateBoolean(mVal->mAttrEnum);
176 nsresult SVGAnimatedBoolean::SMILBool::SetAnimValue(const SMILValue& aValue) {
177 NS_ASSERTION(aValue.mType == SMILBoolType::Singleton(),
178 "Unexpected type to assign animated value");
179 if (aValue.mType == SMILBoolType::Singleton()) {
180 mVal->SetAnimValue(uint16_t(aValue.mU.mBool), mSVGElement);
182 return NS_OK;
185 } // namespace mozilla