SMILCSSProperty.cpp (7107B)
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 "SMILCSSProperty.h" 10 11 #include <utility> 12 13 #include "mozilla/CSSPropertyId.h" 14 #include "mozilla/SMILCSSValueType.h" 15 #include "mozilla/SMILValue.h" 16 #include "mozilla/ServoBindings.h" 17 #include "mozilla/StyleAnimationValue.h" 18 #include "mozilla/dom/Element.h" 19 #include "nsCSSProps.h" 20 #include "nsDOMCSSAttrDeclaration.h" 21 22 namespace mozilla { 23 24 // Class Methods 25 SMILCSSProperty::SMILCSSProperty(NonCustomCSSPropertyId aPropId, 26 dom::Element* aElement, 27 const ComputedStyle* aBaseComputedStyle) 28 : mPropId(aPropId), 29 mElement(aElement), 30 mBaseComputedStyle(aBaseComputedStyle) { 31 MOZ_ASSERT(IsPropertyAnimatable(mPropId), 32 "Creating a SMILCSSProperty for a property " 33 "that's not supported for animation"); 34 } 35 36 SMILValue SMILCSSProperty::GetBaseValue() const { 37 // To benefit from Return Value Optimization and avoid copy constructor calls 38 // due to our use of return-by-value, we must return the exact same object 39 // from ALL return points. This function must only return THIS variable: 40 SMILValue baseValue; 41 42 // SPECIAL CASE: (a) Shorthands 43 // (b) 'display' 44 // (c) No base ComputedStyle 45 if (nsCSSProps::IsShorthand(mPropId) || mPropId == eCSSProperty_display || 46 !mBaseComputedStyle) { 47 // We can't look up the base (computed-style) value of shorthand 48 // properties because they aren't guaranteed to have a consistent computed 49 // value. 50 // 51 // Also, although we can look up the base value of the display property, 52 // doing so involves clearing and resetting the property which can cause 53 // frames to be recreated which we'd like to avoid. 54 // 55 // Furthermore, if we don't (yet) have a base ComputedStyle we obviously 56 // can't resolve a base value. 57 // 58 // In any case, just return a dummy value (initialized with the right 59 // type, so as not to indicate failure). 60 SMILValue tmpVal(&SMILCSSValueType::sSingleton); 61 std::swap(baseValue, tmpVal); 62 return baseValue; 63 } 64 65 AnimationValue computedValue; 66 CSSPropertyId property(mPropId); 67 MOZ_ASSERT(!property.IsCustom(), 68 "Cannot animate custom properties with SMIL"); 69 computedValue.mServo = 70 Servo_ComputedValues_ExtractAnimationValue(mBaseComputedStyle, &property) 71 .Consume(); 72 if (!computedValue.mServo) { 73 return baseValue; 74 } 75 76 baseValue = SMILCSSValueType::ValueFromAnimationValue(mPropId, mElement, 77 computedValue); 78 return baseValue; 79 } 80 81 nsresult SMILCSSProperty::ValueFromString( 82 const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement, 83 SMILValue& aValue, bool& aPreventCachingOfSandwich) const { 84 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropId), NS_ERROR_FAILURE); 85 86 SMILCSSValueType::ValueFromString(mPropId, mElement, aStr, aValue, 87 &aPreventCachingOfSandwich); 88 89 if (aValue.IsNull()) { 90 return NS_ERROR_FAILURE; 91 } 92 93 // XXX Due to bug 536660 (or at least that seems to be the most likely 94 // culprit), when we have animation setting display:none on a <use> element, 95 // if we DON'T set the property every sample, chaos ensues. 96 if (!aPreventCachingOfSandwich && mPropId == eCSSProperty_display) { 97 aPreventCachingOfSandwich = true; 98 } 99 return NS_OK; 100 } 101 102 nsresult SMILCSSProperty::SetAnimValue(const SMILValue& aValue) { 103 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropId), NS_ERROR_FAILURE); 104 return mElement->SMILOverrideStyle()->SetSMILValue(mPropId, aValue); 105 } 106 107 void SMILCSSProperty::ClearAnimValue() { 108 mElement->SMILOverrideStyle()->ClearSMILValue(mPropId); 109 } 110 111 // Based on http://www.w3.org/TR/SVG/propidx.html 112 // static 113 bool SMILCSSProperty::IsPropertyAnimatable(NonCustomCSSPropertyId aPropId) { 114 // NOTE: Right now, Gecko doesn't recognize the following properties from 115 // the SVG Property Index: 116 // alignment-baseline 117 // baseline-shift 118 // color-profile 119 // glyph-orientation-horizontal 120 // glyph-orientation-vertical 121 // kerning 122 // writing-mode 123 124 switch (aPropId) { 125 case eCSSProperty_clip: 126 case eCSSProperty_clip_rule: 127 case eCSSProperty_clip_path: 128 case eCSSProperty_color: 129 case eCSSProperty_color_interpolation: 130 case eCSSProperty_color_interpolation_filters: 131 case eCSSProperty_cursor: 132 case eCSSProperty_display: 133 case eCSSProperty_dominant_baseline: 134 case eCSSProperty_fill: 135 case eCSSProperty_fill_opacity: 136 case eCSSProperty_fill_rule: 137 case eCSSProperty_filter: 138 case eCSSProperty_flood_color: 139 case eCSSProperty_flood_opacity: 140 case eCSSProperty_font: 141 case eCSSProperty_font_family: 142 case eCSSProperty_font_size: 143 case eCSSProperty_font_size_adjust: 144 case eCSSProperty_font_stretch: 145 case eCSSProperty_font_style: 146 case eCSSProperty_font_variant: 147 case eCSSProperty_font_weight: 148 case eCSSProperty_height: 149 case eCSSProperty_image_rendering: 150 case eCSSProperty_letter_spacing: 151 case eCSSProperty_lighting_color: 152 case eCSSProperty_marker: 153 case eCSSProperty_marker_end: 154 case eCSSProperty_marker_mid: 155 case eCSSProperty_marker_start: 156 case eCSSProperty_mask: 157 case eCSSProperty_mask_type: 158 case eCSSProperty_opacity: 159 case eCSSProperty_overflow: 160 case eCSSProperty_pointer_events: 161 case eCSSProperty_shape_rendering: 162 case eCSSProperty_stop_color: 163 case eCSSProperty_stop_opacity: 164 case eCSSProperty_stroke: 165 case eCSSProperty_stroke_dasharray: 166 case eCSSProperty_stroke_dashoffset: 167 case eCSSProperty_stroke_linecap: 168 case eCSSProperty_stroke_linejoin: 169 case eCSSProperty_stroke_miterlimit: 170 case eCSSProperty_stroke_opacity: 171 case eCSSProperty_stroke_width: 172 case eCSSProperty_text_anchor: 173 case eCSSProperty_text_decoration: 174 case eCSSProperty_text_decoration_line: 175 case eCSSProperty_text_rendering: 176 case eCSSProperty_vector_effect: 177 case eCSSProperty_width: 178 case eCSSProperty_visibility: 179 case eCSSProperty_word_spacing: 180 return true; 181 182 // EXPLICITLY NON-ANIMATABLE PROPERTIES: 183 // (Some of these aren't supported at all in Gecko -- I've commented those 184 // ones out. If/when we add support for them, uncomment their line here) 185 // ---------------------------------------------------------------------- 186 // case eCSSProperty_enable_background: 187 // case eCSSProperty_glyph_orientation_horizontal: 188 // case eCSSProperty_glyph_orientation_vertical: 189 // case eCSSProperty_writing_mode: 190 case eCSSProperty_direction: 191 case eCSSProperty_unicode_bidi: 192 return false; 193 194 default: 195 return false; 196 } 197 } 198 199 } // namespace mozilla