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.

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

mercurial