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/. */
6 /* representation of a SMIL-animatable mapped attribute on an element */
7 #include "nsSMILMappedAttribute.h"
8 #include "nsContentUtils.h"
9 #include "nsError.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
10 #include "nsSMILValue.h"
11 #include "nsSMILCSSValueType.h"
12 #include "nsIDocument.h"
13 #include "nsIPresShell.h"
14 #include "nsCSSProps.h"
15 #include "mozilla/dom/Element.h"
17 // Callback function, for freeing string buffers stored in property table
19 ReleaseStringBufferPropertyValue(void* aObject
, /* unused */
20 nsIAtom
* aPropertyName
, /* unused */
22 void* aData
/* unused */)
24 nsStringBuffer
* buf
= static_cast<nsStringBuffer
*>(aPropertyValue
);
30 nsSMILMappedAttribute::ValueFromString(const nsAString
& aStr
,
31 const mozilla::dom::SVGAnimationElement
* aSrcElement
,
33 bool& aPreventCachingOfSandwich
) const
35 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID
), NS_ERROR_FAILURE
);
37 nsSMILCSSValueType::ValueFromString(mPropID
, mElement
, aStr
, aValue
,
38 &aPreventCachingOfSandwich
);
39 return aValue
.IsNull() ? NS_ERROR_FAILURE
: NS_OK
;
43 nsSMILMappedAttribute::GetBaseValue() const
45 nsAutoString baseStringValue
;
46 nsRefPtr
<nsIAtom
> attrName
= GetAttrNameAtom();
47 bool success
= mElement
->GetAttr(kNameSpaceID_None
, attrName
,
49 nsSMILValue baseValue
;
51 // For base values, we don't need to worry whether the value returned is
52 // context-sensitive or not since the compositor will take care of comparing
53 // the returned (computed) base value and its cached value and determining
54 // if an update is required or not.
55 nsSMILCSSValueType::ValueFromString(mPropID
, mElement
,
56 baseStringValue
, baseValue
, nullptr);
58 // Attribute is unset -- use computed value.
59 // FIRST: Temporarily clear animated value, to make sure it doesn't pollute
60 // the computed value. (We want base value, _without_ animations applied.)
61 void* buf
= mElement
->UnsetProperty(SMIL_MAPPED_ATTR_ANIMVAL
,
63 FlushChangesToTargetAttr();
65 // SECOND: we use nsSMILCSSProperty::GetBaseValue to look up the property's
66 // computed value. NOTE: This call will temporarily clear the SMIL
67 // override-style for the corresponding CSS property on our target element.
68 // This prevents any animations that target the CSS property from affecting
69 // animations that target the mapped attribute.
70 baseValue
= nsSMILCSSProperty::GetBaseValue();
72 // FINALLY: If we originally had an animated value set, then set it again.
74 mElement
->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL
, attrName
, buf
,
75 ReleaseStringBufferPropertyValue
);
76 FlushChangesToTargetAttr();
83 nsSMILMappedAttribute::SetAnimValue(const nsSMILValue
& aValue
)
85 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID
), NS_ERROR_FAILURE
);
87 // Convert nsSMILValue to string
89 if (!nsSMILCSSValueType::ValueToString(aValue
, valStr
)) {
90 NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
91 return NS_ERROR_FAILURE
;
94 nsRefPtr
<nsIAtom
> attrName
= GetAttrNameAtom();
95 nsStringBuffer
* oldValStrBuf
= static_cast<nsStringBuffer
*>
96 (mElement
->GetProperty(SMIL_MAPPED_ATTR_ANIMVAL
, attrName
));
99 nsContentUtils::PopulateStringFromStringBuffer(oldValStrBuf
, oldValStr
);
100 if (valStr
.Equals(oldValStr
)) {
101 // New animated value is the same as the old; nothing to do.
106 // Set the string as this mapped attribute's animated value.
107 nsStringBuffer
* valStrBuf
=
108 nsCSSValue::BufferFromString(nsString(valStr
)).take();
109 nsresult rv
= mElement
->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL
,
111 ReleaseStringBufferPropertyValue
);
112 if (rv
== NS_PROPTABLE_PROP_OVERWRITTEN
) {
115 FlushChangesToTargetAttr();
121 nsSMILMappedAttribute::ClearAnimValue()
123 nsRefPtr
<nsIAtom
> attrName
= GetAttrNameAtom();
124 mElement
->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL
, attrName
);
125 FlushChangesToTargetAttr();
129 nsSMILMappedAttribute::FlushChangesToTargetAttr() const
131 // Clear animated content-style-rule
132 mElement
->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL
,
133 SMIL_MAPPED_ATTR_STYLERULE_ATOM
);
134 nsIDocument
* doc
= mElement
->GetCurrentDoc();
136 // Request animation restyle
138 nsIPresShell
* shell
= doc
->GetShell();
140 shell
->RestyleForAnimation(mElement
, eRestyle_Self
);
145 already_AddRefed
<nsIAtom
>
146 nsSMILMappedAttribute::GetAttrNameAtom() const
148 return do_GetAtom(nsCSSProps::GetStringValue(mPropID
));