Bug 1315874 - Pass a base style context to nsSMILCSSProperty; r=heycam draft
authorBrian Birtles <birtles@gmail.com>
Mon, 03 Apr 2017 16:49:10 +0900
changeset 555975 e47894de78368ecdf2b07cd4f21e5348909f30da
parent 555974 392e53f521689422e92643d22189a55f0b491f2e
child 555976 9d8c415a78504f5a06c149d6b933f727a272d7e5
push id52387
push userbbirtles@mozilla.com
push dateWed, 05 Apr 2017 06:09:34 +0000
reviewersheycam
bugs1315874
milestone55.0a1
Bug 1315874 - Pass a base style context to nsSMILCSSProperty; r=heycam We will use this in the next patch in this series to fetch the base style. (I tried simply passing this as a parameter to GetBaseStyle but it proved to be more complicated since all the overrides of GetBaseStyle would need to be updated to take a parameter that would be irrelevant to most of them.) MozReview-Commit-ID: Fdr4rFUlE9V
dom/smil/nsSMILCSSProperty.cpp
dom/smil/nsSMILCSSProperty.h
dom/smil/nsSMILCompositor.cpp
dom/smil/nsSMILCompositor.h
--- a/dom/smil/nsSMILCSSProperty.cpp
+++ b/dom/smil/nsSMILCSSProperty.cpp
@@ -48,18 +48,21 @@ GetCSSComputedValue(Element* aElem,
     NS_NewComputedDOMStyle(aElem, EmptyString(), shell);
 
   computedStyle->GetPropertyValue(aPropID, aResult);
   return true;
 }
 
 // Class Methods
 nsSMILCSSProperty::nsSMILCSSProperty(nsCSSPropertyID aPropID,
-                                     Element* aElement)
-  : mPropID(aPropID), mElement(aElement)
+                                     Element* aElement,
+                                     nsStyleContext* aBaseStyleContext)
+  : mPropID(aPropID)
+  , mElement(aElement)
+  , mBaseStyleContext(aBaseStyleContext)
 {
   MOZ_ASSERT(IsPropertyAnimatable(mPropID),
              "Creating a nsSMILCSSProperty for a property "
              "that's not supported for animation");
 }
 
 nsSMILValue
 nsSMILCSSProperty::GetBaseValue() const
--- a/dom/smil/nsSMILCSSProperty.h
+++ b/dom/smil/nsSMILCSSProperty.h
@@ -10,16 +10,18 @@
 #define NS_SMILCSSPROPERTY_H_
 
 #include "mozilla/Attributes.h"
 #include "nsISMILAttr.h"
 #include "nsIAtom.h"
 #include "nsCSSPropertyID.h"
 #include "nsCSSValue.h"
 
+class nsStyleContext;
+
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 /**
  * nsSMILCSSProperty: Implements the nsISMILAttr interface for SMIL animations
@@ -28,18 +30,24 @@ class Element;
  */
 class nsSMILCSSProperty : public nsISMILAttr
 {
 public:
   /**
    * Constructs a new nsSMILCSSProperty.
    * @param  aPropID   The CSS property we're interested in animating.
    * @param  aElement  The element whose CSS property is being animated.
+   * @param  aBaseStyleContext  The style context to use when getting the base
+   *                            value. If this is nullptr and GetBaseValue is
+   *                            called, an empty nsSMILValue initialized with
+   *                            the nsSMILCSSValueType will be returned.
    */
-  nsSMILCSSProperty(nsCSSPropertyID aPropID, mozilla::dom::Element* aElement);
+  nsSMILCSSProperty(nsCSSPropertyID aPropID,
+                    mozilla::dom::Element* aElement,
+                    nsStyleContext* aBaseStyleContext);
 
   // nsISMILAttr methods
   virtual nsresult ValueFromString(const nsAString& aStr,
                                    const mozilla::dom::SVGAnimationElement* aSrcElement,
                                    nsSMILValue& aValue,
                                    bool& aPreventCachingOfSandwich) const override;
   virtual nsSMILValue GetBaseValue() const override;
   virtual nsresult    SetAnimValue(const nsSMILValue& aValue) override;
@@ -57,11 +65,17 @@ public:
 
 protected:
   nsCSSPropertyID mPropID;
   // Using non-refcounted pointer for mElement -- we know mElement will stay
   // alive for my lifetime because a nsISMILAttr (like me) only lives as long
   // as the Compositing step, and DOM elements don't get a chance to die during
   // that time.
   mozilla::dom::Element*   mElement;
+
+  // The style context to use when fetching base styles.
+  // As with mElement, since an nsISMILAttr only lives as long as the
+  // compositing step and since ComposeAttribute holds an owning reference to
+  // the base style context, we can use a non-owning reference here.
+  nsStyleContext* mBaseStyleContext;
 };
 
 #endif // NS_SMILCSSPROPERTY_H_
--- a/dom/smil/nsSMILCompositor.cpp
+++ b/dom/smil/nsSMILCompositor.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSMILCompositor.h"
 
+#include "nsComputedDOMStyle.h"
 #include "nsCSSProps.h"
 #include "nsHashKeys.h"
 #include "nsSMILCSSProperty.h"
 
 // PLDHashEntryHdr methods
 bool
 nsSMILCompositor::KeyEquals(KeyTypePointer aKey) const
 {
@@ -49,19 +50,28 @@ nsSMILCompositor::AddAnimationFunction(n
 }
 
 void
 nsSMILCompositor::ComposeAttribute(bool& aMightHavePendingStyleUpdates)
 {
   if (!mKey.mElement)
     return;
 
+  // If we might need to resolve base styles, grab a suitable style context
+  // for initializing our nsISMILAttr with.
+  RefPtr<nsStyleContext> baseStyleContext;
+  if (MightNeedBaseStyle()) {
+    baseStyleContext =
+      nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(mKey.mElement,
+                                                           nullptr, nullptr);
+  }
+
   // FIRST: Get the nsISMILAttr (to grab base value from, and to eventually
   // give animated value to)
-  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr();
+  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr(baseStyleContext);
   if (!smilAttr) {
     // Target attribute not found (or, out of memory)
     return;
   }
   if (mAnimationFunctions.IsEmpty()) {
     // No active animation functions. (We can still have a nsSMILCompositor in
     // that case if an animation function has *just* become inactive)
     smilAttr->ClearAnimValue();
@@ -110,33 +120,34 @@ nsSMILCompositor::ComposeAttribute(bool&
 }
 
 void
 nsSMILCompositor::ClearAnimationEffects()
 {
   if (!mKey.mElement || !mKey.mAttributeName)
     return;
 
-  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr();
+  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr(nullptr);
   if (!smilAttr) {
     // Target attribute not found (or, out of memory)
     return;
   }
   smilAttr->ClearAnimValue();
 }
 
 // Protected Helper Functions
 // --------------------------
 UniquePtr<nsISMILAttr>
-nsSMILCompositor::CreateSMILAttr()
+nsSMILCompositor::CreateSMILAttr(nsStyleContext* aBaseStyleContext)
 {
   nsCSSPropertyID propID = GetCSSPropertyToAnimate();
 
   if (propID != eCSSProperty_UNKNOWN) {
-    return MakeUnique<nsSMILCSSProperty>(propID, mKey.mElement.get());
+    return MakeUnique<nsSMILCSSProperty>(propID, mKey.mElement.get(),
+                                         aBaseStyleContext);
   }
 
   return mKey.mElement->GetAnimatedAttr(mKey.mAttributeNamespaceID,
                                         mKey.mAttributeName);
 }
 
 nsCSSPropertyID
 nsSMILCompositor::GetCSSPropertyToAnimate() const
--- a/dom/smil/nsSMILCompositor.h
+++ b/dom/smil/nsSMILCompositor.h
@@ -69,17 +69,21 @@ public:
 
   // Transfers |aOther|'s mCachedBaseValue to |this|
   void StealCachedBaseValue(nsSMILCompositor* aOther) {
     mCachedBaseValue = mozilla::Move(aOther->mCachedBaseValue);
   }
 
  private:
   // Create a nsISMILAttr for my target, on the heap.
-  mozilla::UniquePtr<nsISMILAttr> CreateSMILAttr();
+  //
+  // @param aBaseStyleContext  An optional style context which, if set, will be
+  //                           used when fetching the base style.
+  mozilla::UniquePtr<nsISMILAttr>
+  CreateSMILAttr(nsStyleContext* aBaseStyleContext);
 
   // Returns the CSS property this compositor should animate, or
   // eCSSProperty_UNKNOWN if this compositor does not animate a CSS property.
   nsCSSPropertyID GetCSSPropertyToAnimate() const;
 
   // Returns true if we might need to refer to base styles (i.e. we are
   // targeting a CSS property and have one or more animation functions that
   // don't just replace the underlying value).