1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is the Mozilla SMIL module.
16 : *
17 : * The Initial Developer of the Original Code is the Mozilla Corporation.
18 : * Portions created by the Initial Developer are Copyright (C) 2010
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Daniel Holbert <dholbert@mozilla.com>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /* representation of a SMIL-animatable mapped attribute on an element */
39 : #include "nsSMILMappedAttribute.h"
40 : #include "nsPropertyTable.h"
41 : #include "nsContentErrors.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
42 : #include "nsSMILValue.h"
43 : #include "nsSMILCSSValueType.h"
44 : #include "nsIContent.h"
45 : #include "nsIDocument.h"
46 : #include "nsIPresShell.h"
47 : #include "nsCSSProps.h"
48 : #include "mozilla/dom/Element.h"
49 :
50 : // Callback function, for freeing string buffers stored in property table
51 : static void
52 0 : ReleaseStringBufferPropertyValue(void* aObject, /* unused */
53 : nsIAtom* aPropertyName, /* unused */
54 : void* aPropertyValue,
55 : void* aData /* unused */)
56 : {
57 0 : nsStringBuffer* buf = static_cast<nsStringBuffer*>(aPropertyValue);
58 0 : buf->Release();
59 0 : }
60 :
61 :
62 : nsresult
63 0 : nsSMILMappedAttribute::ValueFromString(const nsAString& aStr,
64 : const nsISMILAnimationElement* aSrcElement,
65 : nsSMILValue& aValue,
66 : bool& aPreventCachingOfSandwich) const
67 : {
68 0 : NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
69 :
70 : nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
71 0 : &aPreventCachingOfSandwich);
72 0 : return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
73 : }
74 :
75 : nsSMILValue
76 0 : nsSMILMappedAttribute::GetBaseValue() const
77 : {
78 0 : nsAutoString baseStringValue;
79 0 : nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
80 : bool success = mElement->GetAttr(kNameSpaceID_None, attrName,
81 0 : baseStringValue);
82 0 : nsSMILValue baseValue;
83 0 : if (success) {
84 : // For base values, we don't need to worry whether the value returned is
85 : // context-sensitive or not since the compositor will take care of comparing
86 : // the returned (computed) base value and its cached value and determining
87 : // if an update is required or not.
88 : nsSMILCSSValueType::ValueFromString(mPropID, mElement,
89 0 : baseStringValue, baseValue, nsnull);
90 : } else {
91 : // Attribute is unset -- use computed value.
92 : // FIRST: Temporarily clear animated value, to make sure it doesn't pollute
93 : // the computed value. (We want base value, _without_ animations applied.)
94 : void* buf = mElement->UnsetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
95 0 : attrName, nsnull);
96 0 : FlushChangesToTargetAttr();
97 :
98 : // SECOND: we use nsSMILCSSProperty::GetBaseValue to look up the property's
99 : // computed value. NOTE: This call will temporarily clear the SMIL
100 : // override-style for the corresponding CSS property on our target element.
101 : // This prevents any animations that target the CSS property from affecting
102 : // animations that target the mapped attribute.
103 0 : baseValue = nsSMILCSSProperty::GetBaseValue();
104 :
105 : // FINALLY: If we originally had an animated value set, then set it again.
106 0 : if (buf) {
107 : mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName, buf,
108 0 : ReleaseStringBufferPropertyValue);
109 0 : FlushChangesToTargetAttr();
110 : }
111 : }
112 : return baseValue;
113 : }
114 :
115 : nsresult
116 0 : nsSMILMappedAttribute::SetAnimValue(const nsSMILValue& aValue)
117 : {
118 0 : NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
119 :
120 : // Convert nsSMILValue to string
121 0 : nsAutoString valStr;
122 0 : if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
123 0 : NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
124 0 : return NS_ERROR_FAILURE;
125 : }
126 :
127 : // Set the string as this mapped attribute's animated value.
128 : nsStringBuffer* valStrBuf =
129 0 : nsCSSValue::BufferFromString(nsString(valStr)).get();
130 0 : nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
131 : nsresult rv = mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
132 : attrName, valStrBuf,
133 0 : ReleaseStringBufferPropertyValue);
134 0 : if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
135 0 : rv = NS_OK;
136 : }
137 0 : FlushChangesToTargetAttr();
138 :
139 0 : return rv;
140 : }
141 :
142 : void
143 0 : nsSMILMappedAttribute::ClearAnimValue()
144 : {
145 0 : nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
146 0 : mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName);
147 0 : FlushChangesToTargetAttr();
148 0 : }
149 :
150 : void
151 0 : nsSMILMappedAttribute::FlushChangesToTargetAttr() const
152 : {
153 : // Clear animated content-style-rule
154 : mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL,
155 0 : SMIL_MAPPED_ATTR_STYLERULE_ATOM);
156 0 : nsIDocument* doc = mElement->GetCurrentDoc();
157 :
158 : // Request animation restyle
159 0 : if (doc) {
160 0 : nsIPresShell* shell = doc->GetShell();
161 0 : if (shell) {
162 0 : shell->RestyleForAnimation(mElement, eRestyle_Self);
163 : }
164 : }
165 0 : }
166 :
167 : already_AddRefed<nsIAtom>
168 0 : nsSMILMappedAttribute::GetAttrNameAtom() const
169 : {
170 0 : return do_GetAtom(nsCSSProps::GetStringValue(mPropID));
171 : }
|