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 : /* representation of a SMIL-animatable CSS property on an element */
8 :
9 : #include "nsSMILCSSProperty.h"
10 :
11 : #include "mozilla/dom/Element.h"
12 : #include "mozilla/Move.h"
13 : #include "mozilla/ServoBindings.h"
14 : #include "mozilla/StyleAnimationValue.h"
15 : #include "nsICSSDeclaration.h"
16 : #include "nsSMILCSSValueType.h"
17 : #include "nsSMILValue.h"
18 : #include "nsCSSProps.h"
19 :
20 : using namespace mozilla;
21 : using namespace mozilla::dom;
22 :
23 : // Class Methods
24 0 : nsSMILCSSProperty::nsSMILCSSProperty(nsCSSPropertyID aPropID,
25 : Element* aElement,
26 0 : nsStyleContext* aBaseStyleContext)
27 : : mPropID(aPropID)
28 : , mElement(aElement)
29 0 : , mBaseStyleContext(aBaseStyleContext)
30 : {
31 0 : MOZ_ASSERT(IsPropertyAnimatable(mPropID,
32 : aElement->OwnerDoc()->GetStyleBackendType()),
33 : "Creating a nsSMILCSSProperty for a property "
34 : "that's not supported for animation");
35 0 : }
36 :
37 : nsSMILValue
38 0 : nsSMILCSSProperty::GetBaseValue() const
39 : {
40 : // To benefit from Return Value Optimization and avoid copy constructor calls
41 : // due to our use of return-by-value, we must return the exact same object
42 : // from ALL return points. This function must only return THIS variable:
43 0 : nsSMILValue baseValue;
44 :
45 : // SPECIAL CASE: (a) Shorthands
46 : // (b) 'display'
47 : // (c) No base style context
48 0 : if (nsCSSProps::IsShorthand(mPropID) ||
49 0 : mPropID == eCSSProperty_display ||
50 0 : !mBaseStyleContext) {
51 : // We can't look up the base (computed-style) value of shorthand
52 : // properties because they aren't guaranteed to have a consistent computed
53 : // value.
54 : //
55 : // Also, although we can look up the base value of the display property,
56 : // doing so involves clearing and resetting the property which can cause
57 : // frames to be recreated which we'd like to avoid.
58 : //
59 : // Furthermore, if we don't (yet) have a base style context we obviously
60 : // can't resolve a base value.
61 : //
62 : // In any case, just return a dummy value (initialized with the right
63 : // type, so as not to indicate failure).
64 0 : nsSMILValue tmpVal(&nsSMILCSSValueType::sSingleton);
65 0 : Swap(baseValue, tmpVal);
66 0 : return baseValue;
67 : }
68 :
69 0 : AnimationValue computedValue;
70 0 : if (mElement->IsStyledByServo()) {
71 : const ServoComputedValues* currentStyle =
72 0 : mBaseStyleContext->ComputedValues();
73 : computedValue.mServo =
74 0 : Servo_ComputedValues_ExtractAnimationValue(currentStyle, mPropID)
75 0 : .Consume();
76 0 : if (!computedValue.mServo) {
77 0 : return baseValue;
78 : }
79 0 : } else if (!StyleAnimationValue::ExtractComputedValue(mPropID,
80 0 : mBaseStyleContext,
81 : computedValue.mGecko)) {
82 0 : return baseValue;
83 : }
84 :
85 : baseValue =
86 0 : nsSMILCSSValueType::ValueFromAnimationValue(mPropID, mElement,
87 0 : computedValue);
88 0 : return baseValue;
89 : }
90 :
91 : nsresult
92 0 : nsSMILCSSProperty::ValueFromString(const nsAString& aStr,
93 : const SVGAnimationElement* aSrcElement,
94 : nsSMILValue& aValue,
95 : bool& aPreventCachingOfSandwich) const
96 : {
97 0 : NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID,
98 : mElement->OwnerDoc()->GetStyleBackendType()),
99 : NS_ERROR_FAILURE);
100 :
101 0 : nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
102 0 : &aPreventCachingOfSandwich);
103 :
104 0 : if (aValue.IsNull()) {
105 0 : return NS_ERROR_FAILURE;
106 : }
107 :
108 : // XXX Due to bug 536660 (or at least that seems to be the most likely
109 : // culprit), when we have animation setting display:none on a <use> element,
110 : // if we DON'T set the property every sample, chaos ensues.
111 0 : if (!aPreventCachingOfSandwich && mPropID == eCSSProperty_display) {
112 0 : aPreventCachingOfSandwich = true;
113 : }
114 0 : return NS_OK;
115 : }
116 :
117 : nsresult
118 0 : nsSMILCSSProperty::SetAnimValue(const nsSMILValue& aValue)
119 : {
120 0 : NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID,
121 : mElement->OwnerDoc()->GetStyleBackendType()),
122 : NS_ERROR_FAILURE);
123 :
124 : // Convert nsSMILValue to string
125 0 : nsAutoString valStr;
126 0 : nsSMILCSSValueType::ValueToString(aValue, valStr);
127 :
128 : // Use string value to style the target element
129 0 : nsICSSDeclaration* overrideDecl = mElement->GetSMILOverrideStyle();
130 0 : if (overrideDecl) {
131 0 : nsAutoString oldValStr;
132 0 : overrideDecl->GetPropertyValue(mPropID, oldValStr);
133 0 : if (valStr.Equals(oldValStr)) {
134 0 : return NS_OK;
135 : }
136 0 : overrideDecl->SetPropertyValue(mPropID, valStr);
137 : }
138 0 : return NS_OK;
139 : }
140 :
141 : void
142 0 : nsSMILCSSProperty::ClearAnimValue()
143 : {
144 : // Put empty string in override style for our property
145 0 : nsICSSDeclaration* overrideDecl = mElement->GetSMILOverrideStyle();
146 0 : if (overrideDecl) {
147 0 : overrideDecl->SetPropertyValue(mPropID, EmptyString());
148 : }
149 0 : }
150 :
151 : // Based on http://www.w3.org/TR/SVG/propidx.html
152 : // static
153 : bool
154 0 : nsSMILCSSProperty::IsPropertyAnimatable(nsCSSPropertyID aPropID,
155 : StyleBackendType aBackend)
156 : {
157 : // Bug 1353918: Drop this check
158 0 : if (aBackend == StyleBackendType::Servo &&
159 0 : !Servo_Property_IsAnimatable(aPropID)) {
160 0 : return false;
161 : }
162 :
163 : // NOTE: Right now, Gecko doesn't recognize the following properties from
164 : // the SVG Property Index:
165 : // alignment-baseline
166 : // baseline-shift
167 : // color-profile
168 : // color-rendering
169 : // glyph-orientation-horizontal
170 : // glyph-orientation-vertical
171 : // kerning
172 : // writing-mode
173 :
174 0 : switch (aPropID) {
175 : case eCSSProperty_clip:
176 : case eCSSProperty_clip_rule:
177 : case eCSSProperty_clip_path:
178 : case eCSSProperty_color:
179 : case eCSSProperty_color_interpolation:
180 : case eCSSProperty_color_interpolation_filters:
181 : case eCSSProperty_cursor:
182 : case eCSSProperty_display:
183 : case eCSSProperty_dominant_baseline:
184 : case eCSSProperty_fill:
185 : case eCSSProperty_fill_opacity:
186 : case eCSSProperty_fill_rule:
187 : case eCSSProperty_filter:
188 : case eCSSProperty_flood_color:
189 : case eCSSProperty_flood_opacity:
190 : case eCSSProperty_font:
191 : case eCSSProperty_font_family:
192 : case eCSSProperty_font_size:
193 : case eCSSProperty_font_size_adjust:
194 : case eCSSProperty_font_stretch:
195 : case eCSSProperty_font_style:
196 : case eCSSProperty_font_variant:
197 : case eCSSProperty_font_weight:
198 : case eCSSProperty_height:
199 : case eCSSProperty_image_rendering:
200 : case eCSSProperty_letter_spacing:
201 : case eCSSProperty_lighting_color:
202 : case eCSSProperty_marker:
203 : case eCSSProperty_marker_end:
204 : case eCSSProperty_marker_mid:
205 : case eCSSProperty_marker_start:
206 : case eCSSProperty_mask:
207 : case eCSSProperty_mask_type:
208 : case eCSSProperty_opacity:
209 : case eCSSProperty_overflow:
210 : case eCSSProperty_pointer_events:
211 : case eCSSProperty_shape_rendering:
212 : case eCSSProperty_stop_color:
213 : case eCSSProperty_stop_opacity:
214 : case eCSSProperty_stroke:
215 : case eCSSProperty_stroke_dasharray:
216 : case eCSSProperty_stroke_dashoffset:
217 : case eCSSProperty_stroke_linecap:
218 : case eCSSProperty_stroke_linejoin:
219 : case eCSSProperty_stroke_miterlimit:
220 : case eCSSProperty_stroke_opacity:
221 : case eCSSProperty_stroke_width:
222 : case eCSSProperty_text_anchor:
223 : case eCSSProperty_text_decoration:
224 : case eCSSProperty_text_decoration_line:
225 : case eCSSProperty_text_rendering:
226 : case eCSSProperty_vector_effect:
227 : case eCSSProperty_width:
228 : case eCSSProperty_visibility:
229 : case eCSSProperty_word_spacing:
230 0 : return true;
231 :
232 : // EXPLICITLY NON-ANIMATABLE PROPERTIES:
233 : // (Some of these aren't supported at all in Gecko -- I've commented those
234 : // ones out. If/when we add support for them, uncomment their line here)
235 : // ----------------------------------------------------------------------
236 : // case eCSSProperty_enable_background:
237 : // case eCSSProperty_glyph_orientation_horizontal:
238 : // case eCSSProperty_glyph_orientation_vertical:
239 : // case eCSSProperty_writing_mode:
240 : case eCSSProperty_direction:
241 : case eCSSProperty_unicode_bidi:
242 0 : return false;
243 :
244 : default:
245 0 : return false;
246 : }
247 : }
|