Bug 436418, patch C3: SVG/SMIL animateMotion - add "TreatSingleValueAsStatic" helper method, to assist nsSMILAnimationFunction subclasses in customizing animation behavior. r=roc
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 28 Apr 2010 16:00:53 -0700
changeset 41503 f33f3bc8fd805f24aa496bbf30e53f1d7b074580
parent 41502 a729bbd470af713d8dca5b2a72bba28f6cb6491e
child 41504 6b47c52ef03af1a21cf67e12614d299fbfb22e5a
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs436418
milestone1.9.3a5pre
Bug 436418, patch C3: SVG/SMIL animateMotion - add "TreatSingleValueAsStatic" helper method, to assist nsSMILAnimationFunction subclasses in customizing animation behavior. r=roc
content/smil/nsSMILAnimationFunction.cpp
content/smil/nsSMILAnimationFunction.h
content/smil/nsSMILSetAnimationFunction.cpp
content/smil/nsSMILSetAnimationFunction.h
--- a/content/smil/nsSMILAnimationFunction.cpp
+++ b/content/smil/nsSMILAnimationFunction.cpp
@@ -243,18 +243,17 @@ nsSMILAnimationFunction::ComposeResult(c
       "Negative sample time for active animation");
   NS_ABORT_IF_FALSE(mSimpleDuration.IsResolved() ||
       mSimpleDuration.IsIndefinite() || mLastValue,
       "Unresolved simple duration for active or frozen animation");
 
   nsSMILValue result(aResult.mType);
 
   if (mSimpleDuration.IsIndefinite() ||
-      (HasAttr(nsGkAtoms::values) && values.Length() == 1)) {
-
+      (values.Length() == 1 && TreatSingleValueAsStatic())) {
     // Indefinite duration or only one value set: Always set the first value
     result = values[0];
 
   } else if (mLastValue) {
 
     // Sampling last value
     nsSMILValue last(values[values.Length() - 1]);
     result = last;
--- a/content/smil/nsSMILAnimationFunction.h
+++ b/content/smil/nsSMILAnimationFunction.h
@@ -322,16 +322,23 @@ protected:
 
   PRBool   ParseAttr(nsIAtom* aAttName, const nsISMILAttr& aSMILAttr,
                      nsSMILValue& aResult, PRBool& aCanCacheSoFar) const;
   nsresult GetValues(const nsISMILAttr& aSMILAttr,
                      nsSMILValueArray& aResult);
   void     CheckKeyTimes(PRUint32 aNumValues);
   void     CheckKeySplines(PRUint32 aNumValues);
 
+  // When GetValues() returns a single-value array, this method indicates
+  // whether that single value can be understood to be a static value, to be
+  // set for the full animation duration.
+  virtual PRBool TreatSingleValueAsStatic() const {
+    return HasAttr(nsGkAtoms::values);
+  }
+
   inline PRBool IsToAnimation() const {
     return !HasAttr(nsGkAtoms::values) &&
             HasAttr(nsGkAtoms::to) &&
            !HasAttr(nsGkAtoms::from);
   }
 
   inline PRBool IsAdditive() const {
     /*
--- a/content/smil/nsSMILSetAnimationFunction.cpp
+++ b/content/smil/nsSMILSetAnimationFunction.cpp
@@ -92,42 +92,16 @@ nsSMILSetAnimationFunction::UnsetAttr(ns
 {
   if (IsDisallowedAttribute(aAttribute)) {
     return PR_TRUE;
   }
 
   return nsSMILAnimationFunction::UnsetAttr(aAttribute);
 }
 
-nsresult
-nsSMILSetAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
-                                              nsSMILValue& aResult,
-                                              nsSMILValue& aBaseValue)
-{
-  // Sanity Checks
-  const nsSMILTime& dur = mSimpleDuration.GetMillis();
-  NS_ABORT_IF_FALSE(mSampleTime >= 0.0f, "Sample time should not be negative");
-  NS_ABORT_IF_FALSE(dur >= 0.0f, "Simple duration should not be negative");
-  NS_ABORT_IF_FALSE(IsToAnimation(), "Set element only supports to-animation");
-
-  if (mSampleTime >= dur || mSampleTime < 0) {
-    NS_ERROR("Animation sampled outside interval");
-    return NS_ERROR_FAILURE;
-  }
-  if (aValues.Length() != 1) {
-    NS_ERROR("Unexpected number of values");
-    return NS_ERROR_FAILURE;
-  }
-  // End Sanity Checks
-
-  // Always use the 'to' value (which should be first & only elem in |aValues|)
-  aResult = aValues[0];
-  return NS_OK;
-}
-
 PRBool
 nsSMILSetAnimationFunction::HasAttr(nsIAtom* aAttName) const
 {
   if (IsDisallowedAttribute(aAttName))
     return PR_FALSE;
 
   return nsSMILAnimationFunction::HasAttr(aAttName);
 }
--- a/content/smil/nsSMILSetAnimationFunction.h
+++ b/content/smil/nsSMILSetAnimationFunction.h
@@ -66,24 +66,26 @@ public:
                          nsAttrValue& aResult, nsresult* aParseResult = nsnull);
 
   /*
    * Unsets the given attribute.
    *
    * @returns PR_TRUE if aAttribute is a recognized animation-related
    *          attribute; PR_FALSE otherwise.
    */
-  virtual PRBool UnsetAttr(nsIAtom* aAttribute);
+  NS_OVERRIDE virtual PRBool UnsetAttr(nsIAtom* aAttribute);
 
 protected:
-  NS_OVERRIDE virtual nsresult
-    InterpolateResult(const nsSMILValueArray& aValues,
-                      nsSMILValue& aResult, nsSMILValue& aBaseValue);
-
-  virtual PRBool             HasAttr(nsIAtom* aAttName) const;
-  virtual const nsAttrValue* GetAttr(nsIAtom* aAttName) const;
-  virtual PRBool             GetAttr(nsIAtom* aAttName,
-                                     nsAString& aResult) const;
+  // <set> uses the "to" attribute as its only source of animation values
+  // (which gives us a single value in our values array), and we want to use
+  // that value whenever the animation is active (no interpolation or anything).
+  NS_OVERRIDE virtual PRBool TreatSingleValueAsStatic() const {
+    return PR_TRUE;
+  }
+  NS_OVERRIDE virtual PRBool             HasAttr(nsIAtom* aAttName) const;
+  NS_OVERRIDE virtual const nsAttrValue* GetAttr(nsIAtom* aAttName) const;
+  NS_OVERRIDE virtual PRBool             GetAttr(nsIAtom* aAttName,
+                                                 nsAString& aResult) const;
 
   PRBool IsDisallowedAttribute(const nsIAtom* aAttribute) const;
 };
 
 #endif // NS_SMILSETANIMATIONFUNCTION_H_