Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / dom / smil / nsSMILMappedAttribute.cpp
blob269e2ea82d73b89c0ebc79662e3746a50fee9a9f
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
18 static void
19 ReleaseStringBufferPropertyValue(void* aObject, /* unused */
20 nsIAtom* aPropertyName, /* unused */
21 void* aPropertyValue,
22 void* aData /* unused */)
24 nsStringBuffer* buf = static_cast<nsStringBuffer*>(aPropertyValue);
25 buf->Release();
29 nsresult
30 nsSMILMappedAttribute::ValueFromString(const nsAString& aStr,
31 const mozilla::dom::SVGAnimationElement* aSrcElement,
32 nsSMILValue& aValue,
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;
42 nsSMILValue
43 nsSMILMappedAttribute::GetBaseValue() const
45 nsAutoString baseStringValue;
46 nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
47 bool success = mElement->GetAttr(kNameSpaceID_None, attrName,
48 baseStringValue);
49 nsSMILValue baseValue;
50 if (success) {
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);
57 } else {
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,
62 attrName, nullptr);
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.
73 if (buf) {
74 mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName, buf,
75 ReleaseStringBufferPropertyValue);
76 FlushChangesToTargetAttr();
79 return baseValue;
82 nsresult
83 nsSMILMappedAttribute::SetAnimValue(const nsSMILValue& aValue)
85 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
87 // Convert nsSMILValue to string
88 nsAutoString valStr;
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));
97 if (oldValStrBuf) {
98 nsString oldValStr;
99 nsContentUtils::PopulateStringFromStringBuffer(oldValStrBuf, oldValStr);
100 if (valStr.Equals(oldValStr)) {
101 // New animated value is the same as the old; nothing to do.
102 return NS_OK;
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,
110 attrName, valStrBuf,
111 ReleaseStringBufferPropertyValue);
112 if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
113 rv = NS_OK;
115 FlushChangesToTargetAttr();
117 return rv;
120 void
121 nsSMILMappedAttribute::ClearAnimValue()
123 nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
124 mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName);
125 FlushChangesToTargetAttr();
128 void
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
137 if (doc) {
138 nsIPresShell* shell = doc->GetShell();
139 if (shell) {
140 shell->RestyleForAnimation(mElement, eRestyle_Self);
145 already_AddRefed<nsIAtom>
146 nsSMILMappedAttribute::GetAttrNameAtom() const
148 return do_GetAtom(nsCSSProps::GetStringValue(mPropID));