dom/smil/nsSMILCSSProperty.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* representation of a SMIL-animatable CSS property on an element */
michael@0 7
michael@0 8 #include "nsSMILCSSProperty.h"
michael@0 9 #include "nsSMILCSSValueType.h"
michael@0 10 #include "nsSMILValue.h"
michael@0 11 #include "nsComputedDOMStyle.h"
michael@0 12 #include "nsCSSProps.h"
michael@0 13 #include "nsStyleAnimation.h"
michael@0 14 #include "mozilla/dom/Element.h"
michael@0 15 #include "nsIDOMElement.h"
michael@0 16 #include "nsIDocument.h"
michael@0 17
michael@0 18 using namespace mozilla::dom;
michael@0 19
michael@0 20 // Helper function
michael@0 21 static bool
michael@0 22 GetCSSComputedValue(Element* aElem,
michael@0 23 nsCSSProperty aPropID,
michael@0 24 nsAString& aResult)
michael@0 25 {
michael@0 26 NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(aPropID),
michael@0 27 "Can't look up computed value of shorthand property");
michael@0 28 NS_ABORT_IF_FALSE(nsSMILCSSProperty::IsPropertyAnimatable(aPropID),
michael@0 29 "Shouldn't get here for non-animatable properties");
michael@0 30
michael@0 31 nsIDocument* doc = aElem->GetCurrentDoc();
michael@0 32 if (!doc) {
michael@0 33 // This can happen if we process certain types of restyles mid-sample
michael@0 34 // and remove anonymous animated content from the document as a result.
michael@0 35 // See bug 534975.
michael@0 36 return false;
michael@0 37 }
michael@0 38
michael@0 39 nsIPresShell* shell = doc->GetShell();
michael@0 40 if (!shell) {
michael@0 41 NS_WARNING("Unable to look up computed style -- no pres shell");
michael@0 42 return false;
michael@0 43 }
michael@0 44
michael@0 45 nsRefPtr<nsComputedDOMStyle> computedStyle =
michael@0 46 NS_NewComputedDOMStyle(aElem, EmptyString(), shell);
michael@0 47
michael@0 48 computedStyle->GetPropertyValue(aPropID, aResult);
michael@0 49 return true;
michael@0 50 }
michael@0 51
michael@0 52 // Class Methods
michael@0 53 nsSMILCSSProperty::nsSMILCSSProperty(nsCSSProperty aPropID,
michael@0 54 Element* aElement)
michael@0 55 : mPropID(aPropID), mElement(aElement)
michael@0 56 {
michael@0 57 NS_ABORT_IF_FALSE(IsPropertyAnimatable(mPropID),
michael@0 58 "Creating a nsSMILCSSProperty for a property "
michael@0 59 "that's not supported for animation");
michael@0 60 }
michael@0 61
michael@0 62 nsSMILValue
michael@0 63 nsSMILCSSProperty::GetBaseValue() const
michael@0 64 {
michael@0 65 // To benefit from Return Value Optimization and avoid copy constructor calls
michael@0 66 // due to our use of return-by-value, we must return the exact same object
michael@0 67 // from ALL return points. This function must only return THIS variable:
michael@0 68 nsSMILValue baseValue;
michael@0 69
michael@0 70 // SPECIAL CASE: (a) Shorthands
michael@0 71 // (b) 'display'
michael@0 72 if (nsCSSProps::IsShorthand(mPropID) || mPropID == eCSSProperty_display) {
michael@0 73 // We can't look up the base (computed-style) value of shorthand
michael@0 74 // properties because they aren't guaranteed to have a consistent computed
michael@0 75 // value.
michael@0 76 //
michael@0 77 // Also, although we can look up the base value of the display property,
michael@0 78 // doing so involves clearing and resetting the property which can cause
michael@0 79 // frames to be recreated which we'd like to avoid.
michael@0 80 //
michael@0 81 // In either case, just return a dummy value (initialized with the right
michael@0 82 // type, so as not to indicate failure).
michael@0 83 nsSMILValue tmpVal(&nsSMILCSSValueType::sSingleton);
michael@0 84 baseValue.Swap(tmpVal);
michael@0 85 return baseValue;
michael@0 86 }
michael@0 87
michael@0 88 // GENERAL CASE: Non-Shorthands
michael@0 89 // (1) Put empty string in override style for property mPropID
michael@0 90 // (saving old override style value, so we can set it again when we're done)
michael@0 91 nsICSSDeclaration* overrideDecl = mElement->GetSMILOverrideStyle();
michael@0 92 nsAutoString cachedOverrideStyleVal;
michael@0 93 if (overrideDecl) {
michael@0 94 overrideDecl->GetPropertyValue(mPropID, cachedOverrideStyleVal);
michael@0 95 // (Don't bother clearing override style if it's already empty)
michael@0 96 if (!cachedOverrideStyleVal.IsEmpty()) {
michael@0 97 overrideDecl->SetPropertyValue(mPropID, EmptyString());
michael@0 98 }
michael@0 99 }
michael@0 100
michael@0 101 // (2) Get Computed Style
michael@0 102 nsAutoString computedStyleVal;
michael@0 103 bool didGetComputedVal = GetCSSComputedValue(mElement, mPropID,
michael@0 104 computedStyleVal);
michael@0 105
michael@0 106 // (3) Put cached override style back (if it's non-empty)
michael@0 107 if (overrideDecl && !cachedOverrideStyleVal.IsEmpty()) {
michael@0 108 overrideDecl->SetPropertyValue(mPropID, cachedOverrideStyleVal);
michael@0 109 }
michael@0 110
michael@0 111 // (4) Populate our nsSMILValue from the computed style
michael@0 112 if (didGetComputedVal) {
michael@0 113 // When we parse animation values we check if they are context-sensitive or
michael@0 114 // not so that we don't cache animation values whose meaning may change.
michael@0 115 // For base values however this is unnecessary since on each sample the
michael@0 116 // compositor will fetch the (computed) base value and compare it against
michael@0 117 // the cached (computed) value and detect changes for us.
michael@0 118 nsSMILCSSValueType::ValueFromString(mPropID, mElement,
michael@0 119 computedStyleVal, baseValue,
michael@0 120 nullptr);
michael@0 121 }
michael@0 122 return baseValue;
michael@0 123 }
michael@0 124
michael@0 125 nsresult
michael@0 126 nsSMILCSSProperty::ValueFromString(const nsAString& aStr,
michael@0 127 const SVGAnimationElement* aSrcElement,
michael@0 128 nsSMILValue& aValue,
michael@0 129 bool& aPreventCachingOfSandwich) const
michael@0 130 {
michael@0 131 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
michael@0 132
michael@0 133 nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
michael@0 134 &aPreventCachingOfSandwich);
michael@0 135
michael@0 136 if (aValue.IsNull()) {
michael@0 137 return NS_ERROR_FAILURE;
michael@0 138 }
michael@0 139
michael@0 140 // XXX Due to bug 536660 (or at least that seems to be the most likely
michael@0 141 // culprit), when we have animation setting display:none on a <use> element,
michael@0 142 // if we DON'T set the property every sample, chaos ensues.
michael@0 143 if (!aPreventCachingOfSandwich && mPropID == eCSSProperty_display) {
michael@0 144 aPreventCachingOfSandwich = true;
michael@0 145 }
michael@0 146 return NS_OK;
michael@0 147 }
michael@0 148
michael@0 149 nsresult
michael@0 150 nsSMILCSSProperty::SetAnimValue(const nsSMILValue& aValue)
michael@0 151 {
michael@0 152 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
michael@0 153
michael@0 154 // Convert nsSMILValue to string
michael@0 155 nsAutoString valStr;
michael@0 156 if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
michael@0 157 NS_WARNING("Failed to convert nsSMILValue for CSS property into a string");
michael@0 158 return NS_ERROR_FAILURE;
michael@0 159 }
michael@0 160
michael@0 161 // Use string value to style the target element
michael@0 162 nsICSSDeclaration* overrideDecl = mElement->GetSMILOverrideStyle();
michael@0 163 if (overrideDecl) {
michael@0 164 nsAutoString oldValStr;
michael@0 165 overrideDecl->GetPropertyValue(mPropID, oldValStr);
michael@0 166 if (valStr.Equals(oldValStr)) {
michael@0 167 return NS_OK;
michael@0 168 }
michael@0 169 overrideDecl->SetPropertyValue(mPropID, valStr);
michael@0 170 }
michael@0 171 return NS_OK;
michael@0 172 }
michael@0 173
michael@0 174 void
michael@0 175 nsSMILCSSProperty::ClearAnimValue()
michael@0 176 {
michael@0 177 // Put empty string in override style for our property
michael@0 178 nsICSSDeclaration* overrideDecl = mElement->GetSMILOverrideStyle();
michael@0 179 if (overrideDecl) {
michael@0 180 overrideDecl->SetPropertyValue(mPropID, EmptyString());
michael@0 181 }
michael@0 182 }
michael@0 183
michael@0 184 // Based on http://www.w3.org/TR/SVG/propidx.html
michael@0 185 // static
michael@0 186 bool
michael@0 187 nsSMILCSSProperty::IsPropertyAnimatable(nsCSSProperty aPropID)
michael@0 188 {
michael@0 189 // NOTE: Right now, Gecko doesn't recognize the following properties from
michael@0 190 // the SVG Property Index:
michael@0 191 // alignment-baseline
michael@0 192 // baseline-shift
michael@0 193 // color-profile
michael@0 194 // color-rendering
michael@0 195 // glyph-orientation-horizontal
michael@0 196 // glyph-orientation-vertical
michael@0 197 // kerning
michael@0 198 // writing-mode
michael@0 199
michael@0 200 switch (aPropID) {
michael@0 201 case eCSSProperty_clip:
michael@0 202 case eCSSProperty_clip_rule:
michael@0 203 case eCSSProperty_clip_path:
michael@0 204 case eCSSProperty_color:
michael@0 205 case eCSSProperty_color_interpolation:
michael@0 206 case eCSSProperty_color_interpolation_filters:
michael@0 207 case eCSSProperty_cursor:
michael@0 208 case eCSSProperty_display:
michael@0 209 case eCSSProperty_dominant_baseline:
michael@0 210 case eCSSProperty_fill:
michael@0 211 case eCSSProperty_fill_opacity:
michael@0 212 case eCSSProperty_fill_rule:
michael@0 213 case eCSSProperty_filter:
michael@0 214 case eCSSProperty_flood_color:
michael@0 215 case eCSSProperty_flood_opacity:
michael@0 216 case eCSSProperty_font:
michael@0 217 case eCSSProperty_font_family:
michael@0 218 case eCSSProperty_font_size:
michael@0 219 case eCSSProperty_font_size_adjust:
michael@0 220 case eCSSProperty_font_stretch:
michael@0 221 case eCSSProperty_font_style:
michael@0 222 case eCSSProperty_font_variant:
michael@0 223 case eCSSProperty_font_weight:
michael@0 224 case eCSSProperty_height:
michael@0 225 case eCSSProperty_image_rendering:
michael@0 226 case eCSSProperty_letter_spacing:
michael@0 227 case eCSSProperty_lighting_color:
michael@0 228 case eCSSProperty_marker:
michael@0 229 case eCSSProperty_marker_end:
michael@0 230 case eCSSProperty_marker_mid:
michael@0 231 case eCSSProperty_marker_start:
michael@0 232 case eCSSProperty_mask:
michael@0 233 case eCSSProperty_mask_type:
michael@0 234 case eCSSProperty_opacity:
michael@0 235 case eCSSProperty_overflow:
michael@0 236 case eCSSProperty_pointer_events:
michael@0 237 case eCSSProperty_shape_rendering:
michael@0 238 case eCSSProperty_stop_color:
michael@0 239 case eCSSProperty_stop_opacity:
michael@0 240 case eCSSProperty_stroke:
michael@0 241 case eCSSProperty_stroke_dasharray:
michael@0 242 case eCSSProperty_stroke_dashoffset:
michael@0 243 case eCSSProperty_stroke_linecap:
michael@0 244 case eCSSProperty_stroke_linejoin:
michael@0 245 case eCSSProperty_stroke_miterlimit:
michael@0 246 case eCSSProperty_stroke_opacity:
michael@0 247 case eCSSProperty_stroke_width:
michael@0 248 case eCSSProperty_text_anchor:
michael@0 249 case eCSSProperty_text_decoration:
michael@0 250 case eCSSProperty_text_decoration_line:
michael@0 251 case eCSSProperty_text_rendering:
michael@0 252 case eCSSProperty_vector_effect:
michael@0 253 case eCSSProperty_width:
michael@0 254 case eCSSProperty_visibility:
michael@0 255 case eCSSProperty_word_spacing:
michael@0 256 return true;
michael@0 257
michael@0 258 // EXPLICITLY NON-ANIMATABLE PROPERTIES:
michael@0 259 // (Some of these aren't supported at all in Gecko -- I've commented those
michael@0 260 // ones out. If/when we add support for them, uncomment their line here)
michael@0 261 // ----------------------------------------------------------------------
michael@0 262 // case eCSSProperty_enable_background:
michael@0 263 // case eCSSProperty_glyph_orientation_horizontal:
michael@0 264 // case eCSSProperty_glyph_orientation_vertical:
michael@0 265 // case eCSSProperty_writing_mode:
michael@0 266 case eCSSProperty_direction:
michael@0 267 case eCSSProperty_unicode_bidi:
michael@0 268 return false;
michael@0 269
michael@0 270 default:
michael@0 271 return false;
michael@0 272 }
michael@0 273 }

mercurial