Index: /cvsroot/mozilla/content/svg/content/src/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/Makefile.in,v
retrieving revision 1.35
diff -u -r1.35 Makefile.in
--- /cvsroot/mozilla/content/svg/content/src/Makefile.in	6 Apr 2005 05:20:41 -0000	1.35
+++ /cvsroot/mozilla/content/svg/content/src/Makefile.in	18 May 2005 11:22:43 -0000
@@ -67,6 +67,7 @@
 
 CPPSRCS		= \
 		nsSVGAngle.cpp \
+		nsSVGAnimateAnimation.cpp \
 		nsSVGAnimatedAngle.cpp \
 		nsSVGAnimatedEnumeration.cpp \
 		nsSVGAnimatedLength.cpp \
@@ -77,10 +78,13 @@
 		nsSVGAnimatedPreserveAspectRatio.cpp \
 		nsSVGAnimatedString.cpp \
 		nsSVGAnimatedTransformList.cpp \
+		nsSVGAnimateElement.cpp \
+		nsSVGAnimationFactory.cpp \
 		nsSVGAtoms.cpp \
 		nsSVGCircleElement.cpp \
 		nsSVGClassValue.cpp \
 		nsSVGClipPathElement.cpp \
+		nsSVGClockValue.cpp \
 		nsSVGCoordCtxProvider.cpp \
 		nsSVGDefsElement.cpp \
 		nsSVGDescElement.cpp \
@@ -123,6 +127,7 @@
 		nsSVGSymbolElement.cpp \
 		nsSVGTSpanElement.cpp \
 		nsSVGTextElement.cpp \
+		nsSVGTimelineManager.cpp \
 		nsSVGTitleElement.cpp \
 		nsSVGTransform.cpp \
 		nsSVGTransformList.cpp \
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimateAnimation.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimateAnimation.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsISVGAnimateAnimation.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGAnimateAnimation.h	18 May 2005 11:22:43 -0000
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_ISVGANIMATEANIMATION__
+#define __NS_ISVGANIMATEANIMATION__
+
+#include "nsISVGAnimation.h"
+
+// {17B3BAE7-B941-4771-8CC9-A06451D9F377}
+#define NS_ISVGANIMATEANIMATION_IID \
+{ 0x17b3bae7, 0xb941, 0x4771, { 0x8c, 0xc9, 0xa0, 0x64, 0x51, 0xd9, 0xf3, 0x77 } }
+
+class nsISVGAnimateAnimation : public nsISVGAnimation
+{
+public:
+  static const nsIID& GetIID()
+    { static nsIID iid = NS_ISVGANIMATEANIMATION_IID; return iid; }
+
+  // The idea here is that these methods would roughly correspond to the
+  // properties of the <animate> element not covered by methods in
+  // nsISVGAnimation.
+  NS_IMETHOD SetFrom(nsSVGAnimationValue& aValue)=0;
+  NS_IMETHOD SetTo(nsSVGAnimationValue& aValue)=0;
+};
+
+#endif // __NS_ISVGANIMATEANIMATION__
+
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimation.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimation.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsISVGAnimation.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGAnimation.h	18 May 2005 11:22:43 -0000
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_ISVGANIMATION__
+#define __NS_ISVGANIMATION__
+
+#include "nsISupports.h"
+
+// {163BDDF1-B4E7-4CBA-BF46-E60490E27EAA}
+#define NS_ISVGANIMATION_IID \
+{ 0x163bddf1, 0xb4e7, 0x4cba, { 0xbf, 0x46, 0xe6, 0x04, 0x90, 0xe2, 0x7e, 0xaa } }
+
+typedef float nsSVGAnimationValue;
+
+/* This could be replaced with a union or something, e.g.
+ *
+ *  typedef union
+ *  {
+ *    nsAString* str;
+ *    float f;
+ *    nsISupports* com;
+ *  } nsSVGAnimationValue;
+ *
+ * Booleans, integers, etc. can be represented as floats. From the SMIL 2.0
+ * spec:
+ *
+ * The semantics of clamping values for attributes should be performed in
+ * floating point with a precision of at least that given by a 4-byte
+ * IEEE-format real number [IEEE-Arithmetic]. Cumulative and additive
+ * presentation values should be computed without regard to the range of the
+ * target attribute. Prior to display, the presentation value should be reduced
+ * or increased to the nearest value which is within the range of the target
+ * attribute. For integer attributes the computed value should then be rounded
+ * to the nearest integer (coerced-integer-value). The mathematical definition
+ * of rounding is:
+ *
+ * coerced-integer-value = Math.floor( interpolated-value + 0.5 )
+ */
+
+class nsISVGValue;
+
+// roc has suggested this sort of this should not be SVG-specific.
+// See: http://wiki.mozilla.org/SVGDev::AnimationController
+class nsISVGAnimation : public nsISupports
+{
+public:
+  static const nsIID& GetIID()
+    { static nsIID iid = NS_ISVGANIMATION_IID; return iid; }
+
+  // These are really two separate interfaces here. One is used by the
+  // timegraph, as in ...
+  NS_IMETHOD StepAnimation(PRInt64 instant, nsISVGValue* value)=0;
+  // Perhaps we could have other methods like GetNextKeyframe, IsRunning etc.
+  // so the animation controller could optimise its operations (e.g. if nothing
+  // is running then pause the animation loop until the next keyframe or until a
+  // RequestUpdate is received from an animation in response to, e.g. an event).
+
+  // ... and the other is used by the animated value and animation elements
+  // (ok, so perhaps even three interfaces) as in ...
+  NS_IMETHOD SetBaseValue(nsSVGAnimationValue& value)=0;
+  NS_IMETHOD GetValue(nsSVGAnimationValue* aValue)=0;
+
+  // So this interface could probably be split up.
+
+  // Perhaps the interface could even be further split up along attribute
+  // collections.
+  //
+  // This interface could contain the stuff that is common to all types
+  // animation elements, i.e. <animate>, <set>,  etc. i.e. Animation.attrib,
+  // AnimationAttribute.attrib, AnimationTiming.attrib but NOT
+  // AnimationValue.attrib or AnimationAddtion.attrib (which aren't used by,
+  // e.g. <set>).
+  //
+  // The idea is that these methods would roughly correspond to the attributes
+  // of the elements. So, if a property was updated via the DOM, the
+  // nsSVG*Element would call the appropriate method on its animation object.
+  // For now, this is an incredibly simplified attempt.
+  NS_IMETHOD SetBegin(PRInt64& aBegin)=0;
+  NS_IMETHOD SetDur(PRInt64& aDur)=0;
+  NS_IMETHOD SetEnd(PRInt64& aEnd)=0;
+
+  // We'd probably also need getters and un-setters (e.g. to indicate when an
+  // attribute is no longer set) -- or we could just use a special value.
+
+  // Perhaps we should pass strings not PRInt64's, i.e. leave the animation
+  // objects to interpret the meaning of begin attributes which can be pretty
+  // complicated. Especially as this functionality will be shared by all
+  // animation elements.
+};
+
+#endif // __NS_ISVGANIMATION__
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimationTarget.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGAnimationTarget.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsISVGAnimationTarget.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGAnimationTarget.h	18 May 2005 11:22:43 -0000
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_ISVGANIMATIONTARGET__
+#define __NS_ISVGANIMATIONTARGET__
+
+#include "nsISupports.h"
+
+////////////////////////////////////////////////////////////////////////
+// nsISVGAnimationTarget: interface of SVG elements which have attributes
+// that can be animated.
+
+// {5DD94E10-FD8D-42FB-B054-8D29F771033A}
+#define NS_ISVGANIMATIONTARGET_IID \
+{ 0x5dd94e10, 0xfd8d, 0x42fb, { 0xb0, 0x54, 0x8d, 0x29, 0xf7, 0x71, 0x03, 0x3a } }
+
+class nsISVGAnimationTarget : public nsISupports
+{
+public:
+  static const nsIID& GetIID() { static nsIID iid = NS_ISVGANIMATIONTARGET_IID; return iid; }
+
+  virtual nsISVGValue* GetAnimatableAttribute(PRInt32 aNamespaceID,
+                                              nsIAtom* aName)=0;
+};
+
+#endif // __NS_ISVGANIMATIONELEMENT__
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGClockValue.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGClockValue.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsISVGClockValue.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGClockValue.h	18 May 2005 11:22:43 -0000
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_ISVGCLOCKVALUE_H__
+#define __NS_ISVGCLOCKVALUE_H__
+
+#include "nsISupports.h"
+
+////////////////////////////////////////////////////////////////////////
+// nsISVGClockValue: private interface for svg clock values
+
+// {fd6ddf02-1078-4fdc-a532-07a93f77136e}
+#define NS_ISVGCLOCKVALUE_IID \
+{ 0xfd6ddf02, 0x1078, 0x4fdc, { 0xa5, 0x32, 0x07, 0xa9, 0x3f, 0x77, 0x13, 0x6e } }
+
+class nsISVGClockValue : public nsISupports
+{
+public:
+  NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGCLOCKVALUE_IID)
+
+  NS_IMETHOD GetValue(PRInt64& aValue)=0;
+  NS_IMETHOD SetValue(const PRInt64& aValue)=0;
+};
+
+#endif // __NS_ISVGCLOCKVALUE_H__
+
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h,v
retrieving revision 1.4
diff -u -r1.4 nsISVGLength.h
--- /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h	5 Aug 2004 09:01:09 -0000	1.4
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGLength.h	18 May 2005 11:22:44 -0000
@@ -56,6 +56,9 @@
   NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGLENGTH_IID)
 
   NS_IMETHOD SetContext(nsSVGCoordCtx* ctx)=0;
+
+protected:
+  NS_IMETHOD GetBaseValue(float* aValue)=0;
 };
 
 
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h,v
retrieving revision 1.5
diff -u -r1.5 nsISVGSVGElement.h
--- /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h	2 Dec 2004 23:13:12 -0000	1.5
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGSVGElement.h	18 May 2005 11:22:44 -0000
@@ -45,6 +45,7 @@
 class nsSVGCoordCtxProvider;
 class nsIDOMSVGNumber;
 class nsISVGEnum;
+class nsISVGTimelineManager;
 
 ////////////////////////////////////////////////////////////////////////
 // nsISVGSVGElement: private interface implemented by <svg>-elements
@@ -60,6 +61,7 @@
   NS_IMETHOD SetParentCoordCtxProvider(nsSVGCoordCtxProvider *parentCtx)=0;
   NS_IMETHOD GetCurrentScaleNumber(nsIDOMSVGNumber **aResult)=0;
   NS_IMETHOD GetZoomAndPanEnum(nsISVGEnum **aResult)=0;
+  NS_IMETHOD GetTimelineManager(nsISVGTimelineManager **aResult)=0;
 };
 
 #endif // __NS_ISVGSVGELEMENT__
Index: /cvsroot/mozilla/content/svg/content/src/nsISVGTimelineManager.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsISVGTimelineManager.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsISVGTimelineManager.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsISVGTimelineManager.h	18 May 2005 11:22:44 -0000
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_ISVGTIMELINEMANAGER_H__
+#define __NS_ISVGTIMELINEMANAGER_H__
+
+#include "nsISupports.h"
+#include "nsISVGAnimation.h"
+
+class nsISVGValue;
+
+////////////////////////////////////////////////////////////////////////
+// nsISVGTimelineManager: Animation controller
+
+// XXX I suppose this interface isn't really necessary
+
+// {32272377-3762-46BD-BCA2-88227E700474}
+#define NS_ISVGTIMELINEMANAGER_IID \
+{ 0x32272377, 0x3762, 0x46bd, { 0xbc, 0xa2, 0x88, 0x22, 0x7e, 0x70, 0x04, 0x74 } }
+
+class nsISVGTimelineManager : public nsISupports
+{
+public:
+  NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGTIMELINEMANAGER_IID)
+
+  NS_IMETHOD RequestUpdate()=0;
+  NS_IMETHOD Shutdown()=0;
+};
+
+#endif // __NS_ISVGTIMELINEMANAGER_H__
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.cpp
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.cpp	18 May 2005 11:22:44 -0000
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSVGAnimateAnimation.h"
+
+#include "nsISVGValue.h"
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGIAnimation implementation for <animate> elements
+
+class nsSVGAnimateAnimation : public nsISVGAnimateAnimation
+{
+public:
+  NS_DECL_ISUPPORTS
+
+  // nsISVGAnimation
+  NS_IMETHOD StepAnimation(PRInt64 instant, nsISVGValue* value);
+  NS_IMETHOD SetBaseValue(nsSVGAnimationValue& value);
+  NS_IMETHOD GetValue(nsSVGAnimationValue* aValue);
+  NS_IMETHOD SetBegin(PRInt64& aBegin);
+  NS_IMETHOD SetDur(PRInt64& aDur);
+  NS_IMETHOD SetEnd(PRInt64& aEnd);
+
+  // nsISVGAnimateAnimation
+  NS_IMETHOD SetFrom(nsSVGAnimationValue& aValue);
+  NS_IMETHOD SetTo(nsSVGAnimationValue& aValue);
+
+protected:
+  friend nsresult NS_NewSVGAnimateAnimation(nsISVGAnimateAnimation** aResult,
+                                            float baseVal);
+
+  nsSVGAnimateAnimation();
+
+  float mBaseValue;
+  PRFloat64 mValue; // This could be replaced with a union or similar, or we
+                    // could define a separate subclass of nsISVGAnimation for
+                    // each type of attribute to animate.
+  
+  PRInt64 mBegin;
+  PRInt64 mDur;
+  PRInt64 mEnd;
+  nsSVGAnimationValue mFrom;
+  nsSVGAnimationValue mTo;
+};
+
+nsSVGAnimateAnimation::nsSVGAnimateAnimation() : mBaseValue(0.0f),
+                                                 mValue(0.0f),
+                                                 mBegin(LL_MinInt()),
+                                                 mDur(LL_MinInt()),
+                                                 mEnd(LL_MinInt()),
+                                                 mFrom(0.0f),
+                                                 mTo(0.0f)
+{ }
+
+//----------------------------------------------------------------------
+// nsISupports methods:
+
+NS_IMPL_ISUPPORTS1(nsSVGAnimateAnimation,
+                   nsISVGAnimateAnimation);
+
+//----------------------------------------------------------------------
+// nsISVGAnimation methods:
+
+// A lot of these methods could be implemented in a common base class and
+// specialised as needed.
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::StepAnimation(PRInt64 instant, nsISVGValue* value)
+{
+  PRFloat64 newValue;
+
+  // Pretend you didn't see this bit...
+
+  if (LL_CMP(instant, <, mBegin))
+    newValue = mBaseValue;
+  else
+  {
+    PRInt64 end = mEnd;
+
+    if (LL_EQ(end, LL_MinInt()))
+      LL_ADD(end, mBegin, mDur);
+
+    if (LL_CMP(instant, >, end))
+      newValue = mTo;
+    else
+    {
+      PRInt64 r;
+      PRFloat64 progress;
+      PRFloat64 length;
+
+      LL_SUB(r, instant, mBegin);
+      LL_L2D(progress, r);
+      LL_SUB(r, end, mBegin);
+      LL_L2D(length, r);
+      
+      newValue = mFrom + (progress / length) * (mTo - mFrom);
+    }
+  }
+
+  if (mValue != newValue)
+  {
+    value->BeginBatchUpdate();
+    mValue = newValue; 
+    value->EndBatchUpdate();
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetBaseValue(nsSVGAnimationValue& value)
+{
+  mBaseValue = value;
+  mValue = mBaseValue;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::GetValue(nsSVGAnimationValue* aValue)
+{
+  *aValue = NS_STATIC_CAST(nsSVGAnimationValue, mValue);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetBegin(PRInt64& aBegin)
+{
+  mBegin = aBegin;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetDur(PRInt64& aDur)
+{
+  mDur = aDur;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetEnd(PRInt64& aEnd)
+{
+  mEnd = aEnd;
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsISVGAnimateAnimation methods:
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetFrom(nsSVGAnimationValue& aValue)
+{
+  mFrom = aValue;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGAnimateAnimation::SetTo(nsSVGAnimationValue& aValue)
+{
+  mTo = aValue;
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+nsresult NS_NewSVGAnimateAnimation(nsISVGAnimateAnimation** aResult,
+                                   float baseVal)
+{
+  *aResult = nsnull;
+  
+  nsSVGAnimateAnimation* animation = new nsSVGAnimateAnimation();
+  if(!animation) return NS_ERROR_OUT_OF_MEMORY;
+  NS_ADDREF(animation);
+
+  animation->SetBaseValue(baseVal);
+  
+  *aResult = (nsISVGAnimateAnimation*) animation;
+  
+  return NS_OK;
+}
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateAnimation.h	18 May 2005 11:22:44 -0000
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_SVGANIMATEANIMATION_H__
+#define __NS_SVGANIMATEANIMATION_H__
+
+#include "nsISVGAnimateAnimation.h"
+
+//----------------------------------------------------------------------
+// Implementation of nsISVGAnimation for <animate> elements.
+
+nsresult NS_NewSVGAnimateAnimation(nsISVGAnimateAnimation** aResult,
+                                   float baseVal);
+
+#endif // __NS_SVGANIMATEANIMATION_H__
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimateElement.cpp	18 May 2005 11:22:45 -0000
@@ -0,0 +1,499 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSVGElement.h"
+#include "nsIDOMSVGAnimateElement.h"
+#include "nsSVGAtoms.h"
+#include "nsISVGSVGElement.h"
+#include "nsIBindingManager.h"
+#include "nsIDocument.h"
+#include "nsISVGAnimationTarget.h"
+#include "nsISVGClockValue.h"
+#include "nsSVGClockValue.h"
+#include "nsSVGAnimationFactory.h"
+#include "nsISVGAnimateAnimation.h"
+#include "nsSVGNumber.h"
+#include "nsSVGTimelineManager.h"
+
+typedef nsSVGElement nsSVGAnimateElementBase;
+
+class nsSVGAnimateElement : public nsSVGAnimateElementBase,
+                            public nsIDOMSVGAnimateElement
+                              // : nsIDOMSVGAnimationElement
+{
+protected:
+  friend nsresult NS_NewSVGAnimateElement(nsIContent **aResult,
+                                          nsINodeInfo *aNodeInfo);
+  nsSVGAnimateElement(nsINodeInfo* aNodeInfo);
+  nsresult Init();
+
+public:
+  // interfaces:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIDOMSVGANIMATEELEMENT
+  NS_DECL_NSIDOMSVGANIMATIONELEMENT
+
+  NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsSVGAnimateElementBase::)
+  NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateElementBase::)
+  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateElementBase::)
+
+  // nsISVGContent specializations
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              PRBool aCompileEventHandlers);
+  virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
+                              PRBool aNullParent = PR_TRUE);
+  virtual void ParentChainChanged();
+
+  // nsIContent specializations
+  virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                           nsIAtom* aPrefix, const nsAString& aValue,
+                           PRBool aNotify);
+  virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+                             PRBool aNotify);
+
+protected:
+  void UpdateTimelineManager();
+  void UpdateTargetElement();
+  void UpdateTargetAttribute();
+  void CreateAnimation(nsISVGAnimateAnimation** aAnimation);
+
+  nsWeakPtr                         mTargetElement;
+  nsWeakPtr                         mTimelineManager;
+  nsCOMPtr<nsISVGAnimateAnimation>  mAnimation;
+
+  nsCOMPtr<nsISVGClockValue>        mBegin;
+  nsCOMPtr<nsISVGClockValue>        mDur;
+  nsCOMPtr<nsISVGClockValue>        mEnd;
+
+  // Just doing numbers for now, in the future we could make this a string
+  nsCOMPtr<nsIDOMSVGNumber>         mFrom;
+  nsCOMPtr<nsIDOMSVGNumber>         mTo;
+};
+
+NS_IMPL_NS_NEW_SVG_ELEMENT(Animate)
+
+
+//----------------------------------------------------------------------
+// nsISupports methods
+
+NS_IMPL_ADDREF_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase)
+NS_IMPL_RELEASE_INHERITED(nsSVGAnimateElement,nsSVGAnimateElementBase)
+
+NS_INTERFACE_MAP_BEGIN(nsSVGAnimateElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimationElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimateElement)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimateElement)
+NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimateElementBase)
+
+//----------------------------------------------------------------------
+// Implementation
+
+nsSVGAnimateElement::nsSVGAnimateElement(nsINodeInfo *aNodeInfo)
+  : nsSVGAnimateElementBase(aNodeInfo)
+{
+}
+
+nsresult
+nsSVGAnimateElement::Init()
+{
+  nsresult rv;
+
+  // XXX This is completely wrong, these attributes can be many things apart
+  // from a clock value.
+
+  // #IMPLIED attrib: begin
+  {
+    rv = NS_NewSVGClockValue(getter_AddRefs(mBegin), LL_MinInt());
+    NS_ENSURE_SUCCESS(rv,rv);
+    rv = AddMappedSVGValue(nsSVGAtoms::begin, mBegin);
+    NS_ENSURE_SUCCESS(rv,rv);
+  }
+
+  // #IMPLIED attrib: dur
+  {
+    rv = NS_NewSVGClockValue(getter_AddRefs(mDur), LL_MinInt());
+    NS_ENSURE_SUCCESS(rv,rv);
+    rv = AddMappedSVGValue(nsSVGAtoms::dur, mDur);
+    NS_ENSURE_SUCCESS(rv,rv);
+  }
+
+  // #IMPLIED attrib: end
+  {
+    rv = NS_NewSVGClockValue(getter_AddRefs(mEnd), LL_MinInt());
+    NS_ENSURE_SUCCESS(rv,rv);
+    rv = AddMappedSVGValue(nsSVGAtoms::end, mEnd);
+    NS_ENSURE_SUCCESS(rv,rv);
+  }
+
+  // #IMPLIED attrib: from
+  {
+    rv = NS_NewSVGNumber(getter_AddRefs(mFrom), 0.0f);
+    NS_ENSURE_SUCCESS(rv,rv);
+    rv = AddMappedSVGValue(nsSVGAtoms::from, mFrom);
+    NS_ENSURE_SUCCESS(rv,rv);
+  }
+
+  // #IMPLIED attrib: to
+  {
+    rv = NS_NewSVGNumber(getter_AddRefs(mTo), 0.0f);
+    NS_ENSURE_SUCCESS(rv,rv);
+    rv = AddMappedSVGValue(nsSVGAtoms::to, mTo);
+    NS_ENSURE_SUCCESS(rv,rv);
+  }
+
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsIDOMSVGAnimationElement methods
+
+/* readonly attribute SVGElement targetElement; */
+NS_IMETHODIMP nsSVGAnimateElement::GetTargetElement(nsIDOMSVGElement * *aTarget)
+{
+  if (mTargetElement)
+  {
+    nsCOMPtr<nsIDOMSVGElement> weakref = do_QueryReferent(mTargetElement);
+    if (*aTarget)
+      NS_RELEASE(*aTarget);
+    NS_IF_ADDREF(*aTarget = weakref);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsSVGAnimateElement::GetStartTime(float* retval)
+{
+  nsresult rv = NS_OK;
+
+  // For now we just support simple clock values
+  if (mBegin)
+  {
+    PRInt64 valueMillis;
+    PRInt64 valueSeconds;
+
+    mBegin->GetValue(valueMillis);
+    LL_DIV(valueSeconds, valueMillis, PR_MSEC_PER_SEC);
+    LL_L2F(*retval, valueSeconds);
+  }
+  else
+  {
+    rv = NS_ERROR_FAILURE;
+  }
+
+  return rv;
+}
+
+NS_IMETHODIMP nsSVGAnimateElement::GetCurrentTime(float* retval)
+{
+  // XXX query the timegraph
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsSVGAnimateElement::GetSimpleDuration(float* retval)
+{
+  // XXX query the nsISVGAnimateAnimation object
+  return NS_OK;
+}
+
+
+//----------------------------------------------------------------------
+// nsIDOMNode methods
+
+NS_IMPL_DOM_CLONENODE_WITH_INIT(nsSVGAnimateElement)
+
+
+//----------------------------------------------------------------------
+// nsISVGContent methods
+
+nsresult nsSVGAnimateElement::BindToTree(nsIDocument* aDocument,
+                                         nsIContent* aParent,
+                                         nsIContent* aBindingParent,
+                                         PRBool aCompileEventHandlers)
+{
+  nsresult rv = nsSVGAnimateElementBase::BindToTree(aDocument, aParent,
+                                                    aBindingParent,
+                                                    aCompileEventHandlers);
+  UpdateTimelineManager();
+
+  return rv;
+}
+
+void nsSVGAnimateElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
+{
+  nsSVGAnimateElementBase::UnbindFromTree(aDeep, aNullParent);
+  if (mAnimation)
+    nsSVGTimelineManager::UnregisterAnimation(mAnimation);
+  mTimelineManager = nsnull;
+}
+
+void nsSVGAnimateElement::ParentChainChanged()
+{
+  UpdateTargetElement();
+  nsSVGAnimateElementBase::ParentChainChanged();
+}  
+
+//----------------------------------------------------------------------
+// nsIContent methods
+
+nsresult nsSVGAnimateElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                      nsIAtom* aPrefix, const nsAString& aValue,
+                                      PRBool aNotify)
+{
+  nsresult rv = nsSVGAnimateElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
+                                                 aValue, aNotify);
+  
+  // Replace with observing I suppose
+
+  if (aName == nsSVGAtoms::attributeName)
+    UpdateTargetAttribute();
+
+  // As mentioned in nsISVGAnimateAnimation.h we could actually interpret
+  // things like begin attribute lists in nsSVGAnimation.cpp (which doesn't
+  // exist yet) rather than doing it here.
+  if (mAnimation)
+  {
+    if (aName == nsSVGAtoms::begin)
+    {
+      PRInt64 instant;
+      mBegin->GetValue(instant);
+      mAnimation->SetBegin(instant);
+    }
+    else if (aName == nsSVGAtoms::dur)
+    {
+      PRInt64 instant;
+      mDur->GetValue(instant);
+      mAnimation->SetDur(instant);
+    }
+    else if (aName == nsSVGAtoms::end)
+    {
+      PRInt64 instant;
+      mEnd->GetValue(instant);
+      mAnimation->SetEnd(instant);
+    }
+    else if (aName == nsSVGAtoms::from)
+    {
+      float from;
+      mFrom->GetValue(&from);
+      mAnimation->SetFrom(from);
+    }
+    else if (aName == nsSVGAtoms::to)
+    {
+      float to;
+      mTo->GetValue(&to);
+      mAnimation->SetTo(to);
+    }
+  }
+
+  return rv;
+}
+
+nsresult nsSVGAnimateElement::UnsetAttr(PRInt32 aNameSpaceID,
+                                        nsIAtom* aAttribute, PRBool aNotify)
+{
+  nsresult rv = nsSVGAnimateElementBase::UnsetAttr(aNameSpaceID, aAttribute,
+                                                   aNotify);
+  if (aAttribute == nsSVGAtoms::attributeName)
+    UpdateTargetAttribute();
+    // XXX Is unsetting the attribute name ever not an error?
+
+  // XXX have to deal with unsetting other stuff
+
+  return rv;
+}
+
+//----------------------------------------------------------------------
+// Implementation helpers
+
+void nsSVGAnimateElement::UpdateTimelineManager()
+{
+  nsresult rv;
+  nsCOMPtr<nsISVGSVGElement>      ownerSVG;
+  nsCOMPtr<nsISVGTimelineManager> parentTimeline;
+  nsCOMPtr<nsIDOMSVGSVGElement>   ownerDOMSVG;
+  rv = GetOwnerSVGElement(getter_AddRefs(ownerDOMSVG));
+
+  if (rv == NS_OK && ownerDOMSVG)
+  {
+    ownerSVG = do_QueryInterface(ownerDOMSVG, &rv);
+
+    if (rv == NS_OK && ownerSVG)
+      rv = ownerSVG->GetTimelineManager(getter_AddRefs(parentTimeline));
+  }
+
+  if (rv == NS_OK && parentTimeline)
+  {
+    nsCOMPtr<nsISVGTimelineManager> myTimeline = 
+      do_QueryReferent(mTimelineManager);
+
+    if (myTimeline != parentTimeline)
+      mTimelineManager = do_GetWeakReference(parentTimeline);
+  }
+  else
+  {
+    /* We don't have an owner <svg> or at least we can't fetch it's timeline
+     * manager -- maybe the tree is being destroyed, or we are being removed
+     * from the tree. Try to unregister ourselves but if we can't, don't worry
+     * about it (the timeline manager may have already been destroyed). */
+    if (mAnimation)
+      nsSVGTimelineManager::UnregisterAnimation(mAnimation);
+  }
+}
+
+void nsSVGAnimateElement::UpdateTargetElement()
+{
+  // XXX Follow xlink:href attributes when provided
+
+  nsIBindingManager *bindingManager = nsnull;
+  nsIDocument *ownerDoc = GetOwnerDoc();
+
+  if (ownerDoc)
+  {
+    bindingManager = ownerDoc->BindingManager();
+  }
+
+  nsCOMPtr<nsIContent> parent;
+
+  if (bindingManager)
+  {
+    // we have a binding manager -- do we have an anonymous parent?
+    bindingManager->GetInsertionParent(this, getter_AddRefs(parent));
+  }
+
+  if (!parent)
+  {
+    // if we didn't find an anonymous parent, use the explicit one,
+    // whether it's null or not...
+    parent = GetParent();
+  }
+
+  if (parent)
+  {
+    nsWeakPtr parentElement = do_GetWeakReference(parent);
+    if (parentElement && mTargetElement != parentElement)
+    {
+      mTargetElement = parentElement;
+      UpdateTargetAttribute();
+    }
+    else
+    {
+      mTargetElement = nsnull;
+      mAnimation = nsnull;
+    }
+  }
+  else
+  {
+    mTargetElement = nsnull;
+    mAnimation = nsnull;
+  }
+}
+
+void nsSVGAnimateElement::UpdateTargetAttribute()
+{
+  // XXX Implement XML vs CSS vs auto attribute types
+  
+  // All this is much more complicated than it needs to be. It's just leftover
+  // from a previous implementation.
+
+  if (mTargetElement)
+  {
+    nsAutoString attributeName;
+
+    GetAttr(kNameSpaceID_None, nsSVGAtoms::attributeName, attributeName);
+
+    nsCOMPtr<nsIAtom> attributeAtom( do_GetAtom(attributeName) );
+    nsCOMPtr<nsISVGAnimationTarget> 
+      targetElement(do_QueryReferent(mTargetElement));
+
+    if (targetElement)
+    {
+      nsCOMPtr<nsISVGValue> targetAttribute = 
+        targetElement->GetAnimatableAttribute(kNameSpaceID_None, attributeAtom);
+      if (targetAttribute)
+      {
+        if (mAnimation)
+          nsSVGTimelineManager::UnregisterAnimation(mAnimation);
+
+        nsISVGAnimateAnimation* animation = nsnull;
+        nsISVGValue* animVal = nsnull;
+        nsresult rv = 
+          nsSVGAnimationFactory::NewAnimateAnimation(targetAttribute,
+                                                     &animation,
+                                                     &animVal);
+        if (rv == NS_OK)
+        {
+          PRInt64 instant;
+          float val;
+
+          mAnimation = animation;
+
+          mBegin->GetValue(instant);
+          if (LL_NE(instant, LL_MinInt())) mAnimation->SetBegin(instant);
+
+          mDur->GetValue(instant);
+          if (LL_NE(instant, LL_MinInt())) mAnimation->SetDur(instant);
+    
+          mEnd->GetValue(instant);
+          if (LL_NE(instant, LL_MinInt())) mAnimation->SetEnd(instant);
+
+          mFrom->GetValue(&val);
+          mAnimation->SetFrom(val);
+
+          mTo->GetValue(&val);
+          mAnimation->SetTo(val);
+
+          nsSVGTimelineManager::RegisterAnimation(animVal, mAnimation);
+        }
+        else
+        {
+          // XXX Mark document as in error, attribute not animatable
+        }
+      }
+      else
+      {
+        // XXX Mark document in error, attribute doesn't exist or isn't
+        // animatable
+      }
+    }
+    else
+    {
+      // XXX Mark document as in error
+    }
+    // XXX Try casting to different types of animatable objects
+  }
+  /* else: We may still be loading, ignore for now. This will be called again
+   * when our parent changes. */
+}
+
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp,v
retrieving revision 1.8
diff -u -r1.8 nsSVGAnimatedLength.cpp
--- /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp	31 Jan 2005 19:45:10 -0000	1.8
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimatedLength.cpp	18 May 2005 11:22:46 -0000
@@ -79,7 +79,7 @@
   // implementation inherited from nsSupportsWeakReference
   
 protected:
-  nsCOMPtr<nsIDOMSVGLength> mBaseVal;
+  nsSVGLength*              mBaseVal;
 };
 
 
@@ -89,22 +89,28 @@
 
 nsSVGAnimatedLength::nsSVGAnimatedLength()
 {
+  mBaseVal = nsnull;
 }
 
 nsSVGAnimatedLength::~nsSVGAnimatedLength()
 {
   if (!mBaseVal) return;
-  nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
+  nsCOMPtr<nsISVGValue> val
+      = do_QueryInterface(NS_STATIC_CAST(nsSVGLength__B__*, mBaseVal));
   if (!val) return;
   val->RemoveObserver(this);
+  NS_IF_RELEASE(mBaseVal);
 }
 
 void
 nsSVGAnimatedLength::Init(nsIDOMSVGLength* baseVal)
 {
-  mBaseVal = baseVal;
+  NS_IF_RELEASE(mBaseVal);
+  mBaseVal = NS_REINTERPRET_CAST(nsSVGLength*, baseVal);
   if (!mBaseVal) return;
-  nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
+  NS_ADDREF(mBaseVal);
+  nsCOMPtr<nsISVGValue> val
+      = do_QueryInterface(NS_STATIC_CAST(nsSVGLength__B__*, mBaseVal));
   NS_ASSERTION(val, "baseval needs to implement nsISVGValue interface");
   if (!val) return;
   val->AddObserver(this);
@@ -132,14 +138,16 @@
 NS_IMETHODIMP
 nsSVGAnimatedLength::SetValueString(const nsAString& aValue)
 {
-  nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
+  nsCOMPtr<nsISVGValue> value
+      = do_QueryInterface(NS_STATIC_CAST(nsSVGLength__B__*, mBaseVal));
   return value->SetValueString(aValue);
 }
 
 NS_IMETHODIMP
 nsSVGAnimatedLength::GetValueString(nsAString& aValue)
 {
-  nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
+  nsCOMPtr<nsISVGValue> value
+      = do_QueryInterface(NS_STATIC_CAST(nsSVGLength__B__*, mBaseVal));
   return value->GetValueString(aValue);
 }
 
@@ -150,7 +158,7 @@
 NS_IMETHODIMP
 nsSVGAnimatedLength::GetBaseVal(nsIDOMSVGLength * *aBaseVal)
 {
-  *aBaseVal = mBaseVal;
+  *aBaseVal = NS_STATIC_CAST(nsSVGLength__B__*, mBaseVal);
   NS_ADDREF(*aBaseVal);
   return NS_OK;
 }
@@ -159,7 +167,7 @@
 NS_IMETHODIMP
 nsSVGAnimatedLength::GetAnimVal(nsIDOMSVGLength * *aAnimVal)
 {
-  *aAnimVal = mBaseVal;
+  *aAnimVal = NS_STATIC_CAST(nsSVGLength__A__*, mBaseVal);
   NS_ADDREF(*aAnimVal);
   return NS_OK;
 }
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.cpp
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.cpp	18 May 2005 11:22:47 -0000
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSVGAnimationFactory.h"
+
+#include "nsCOMPtr.h"
+#include "nsSVGAnimateAnimation.h"
+#include "nsIDOMSVGAnimatedAngle.h"
+#include "nsIDOMSVGAnimatedEnum.h"
+#include "nsIDOMSVGAnimatedLength.h"
+#include "nsIDOMSVGAnimatedLengthList.h"
+#include "nsIDOMSVGAnimatedNumber.h"
+#include "nsIDOMSVGAnimatedNumberList.h"
+#include "nsIDOMSVGAnimPresAspRatio.h"
+#include "nsIDOMSVGAnimatedRect.h"
+#include "nsIDOMSVGAnimatedString.h"
+#include "nsIDOMSVGAnimTransformList.h"
+#include "nsIDOMSVGLength.h"
+
+/*
+ * The aValue parameter is just a helper so the caller can use this value to
+ * register with the timegraph.
+ */
+
+NS_METHOD
+nsSVGAnimationFactory::NewAnimateAnimation(nsISVGValue* const value,
+                                           nsISVGAnimateAnimation** aResult,
+                                           nsISVGValue** aValue)
+{
+  nsresult result = NS_OK;
+  nsCOMPtr<nsISupports> castResult;
+  nsCOMPtr<nsIDOMSVGAnimatedLength> length;
+
+  // This should be sorted according to the most commonly used types (e.g. more
+  // likely to animate lengths than angles, e.g.(ii) more attributes are of type
+  // nsSVGAnimatedNumber than nsSVGAnimatedTransformList).
+
+  if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedAngle), getter_AddRefs(castResult))
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating angles
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedEnumeration), getter_AddRefs(castResult)) 
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating enumerations
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedLength), getter_AddRefs(length)) 
+      == NS_OK)
+  {
+    nsCOMPtr<nsIDOMSVGLength> baseVal;
+    length->GetBaseVal(getter_AddRefs(baseVal));
+    float val;
+    baseVal->GetValue(&val);
+    NS_NewSVGAnimateAnimation(aResult, val);
+
+    nsCOMPtr<nsIDOMSVGLength> animVal;
+    length->GetAnimVal(getter_AddRefs(animVal));
+    nsCOMPtr<nsISVGValue> svgVal( do_QueryInterface(animVal) );
+    result = CallQueryInterface(animVal, aValue);
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedLengthList), getter_AddRefs(castResult)) 
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating length lists
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedNumber), getter_AddRefs(castResult)) 
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating numbers
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedNumberList), getter_AddRefs(castResult)) 
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating number lists
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedPreserveAspectRatio),
+    getter_AddRefs(castResult))
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating preserve aspect
+    // ratios
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedRect), getter_AddRefs(castResult))
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating rects
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedString), getter_AddRefs(castResult)) 
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating strings
+  }
+  else if (value->QueryInterface(
+    NS_GET_IID(nsIDOMSVGAnimatedTransformList), getter_AddRefs(castResult))
+      == NS_OK)
+  {
+    // Create an animation strategy object for animating transform lists
+  }
+  else
+  {
+    // XXX The caller should mark the document in error. The attribute isn't
+    // animatable.
+    result = NS_ERROR_FAILURE;
+  }
+
+  return result;
+}
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAnimationFactory.h	18 May 2005 11:22:47 -0000
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_SVGANIMATIONFACTORY_H__
+#define __NS_SVGANIMATIONFACTORY_H__
+
+#include "nsISVGAnimateAnimation.h"
+#include "nsISVGValue.h"
+
+/*
+ * Not quite sure what possessed me to create this class. I think it depends
+ * on how we handle animating different kinds of values. Perhaps if we're
+ * going to pass in a different strategy object depending on the type of
+ * value it makes sense.
+ *
+ * This doesn't really need to be wrapped in an object. Actually it's probably
+ * inconsistent to do so.
+ */
+
+class nsSVGAnimationFactory
+{
+public:
+  static NS_METHOD NewAnimateAnimation(nsISVGValue* const value,
+                                       nsISVGAnimateAnimation** aResult,
+                                       nsISVGValue** aValue);
+
+  // methods for creating animation objects for animating colour, motion etc.
+  // could go here
+
+protected:
+  nsSVGAnimationFactory() { }
+};
+
+#endif // __NS_SVGANIMATIONFACTORY_H__
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h,v
retrieving revision 1.21
diff -u -r1.21 nsSVGAtomList.h
--- /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h	7 Mar 2005 04:02:02 -0000	1.21
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGAtomList.h	18 May 2005 11:22:47 -0000
@@ -55,6 +55,7 @@
  ******/
 
 // tags
+SVG_ATOM(animate, "animate")
 SVG_ATOM(circle, "circle")
 SVG_ATOM(clipPath, "clipPath")
 SVG_ATOM(defs, "defs")
@@ -86,9 +87,16 @@
 
   
 // properties and attributes
+SVG_ATOM(accumulate, "accumulate")
+SVG_ATOM(additive, "additive")
 SVG_ATOM(alignment_baseline, "alignment-baseline")
+SVG_ATOM(attributeName, "attributeName")
+SVG_ATOM(attributeType, "attributeType")
 SVG_ATOM(_auto, "auto")
 SVG_ATOM(baseline_shift, "baseline-shift")
+SVG_ATOM(begin, "begin")
+SVG_ATOM(by, "by")
+SVG_ATOM(calcMode, "calcMode")
 SVG_ATOM(_class, "class")
 SVG_ATOM(clip, "clip")
 SVG_ATOM(clip_path, "clip-path")
@@ -102,8 +110,10 @@
 SVG_ATOM(direction, "direction")
 SVG_ATOM(display, "display")
 SVG_ATOM(dominant_baseline, "dominant-baseline")
+SVG_ATOM(dur, "dur")
 SVG_ATOM(dx, "dx")
 SVG_ATOM(dy, "dy")
+SVG_ATOM(end, "end")
 SVG_ATOM(fill, "fill")
 SVG_ATOM(fill_opacity, "fill-opacity")
 SVG_ATOM(fill_rule, "fill-rule")
@@ -115,6 +125,7 @@
 SVG_ATOM(font_style, "font-style")
 SVG_ATOM(font_variant, "font-variant")
 SVG_ATOM(font_weight, "font-weight")
+SVG_ATOM(from, "from")
 SVG_ATOM(fx, "fx")
 SVG_ATOM(fy, "fy")
 SVG_ATOM(glyph_orientation_horizontal, "glyph-orientation-horizontal")
@@ -126,6 +137,8 @@
 SVG_ATOM(id, "id")
 SVG_ATOM(image_rendering, "image-rendering")
 SVG_ATOM(kerning, "kerning")
+SVG_ATOM(keySplines, "keySplines")
+SVG_ATOM(keyTimes, "keyTimes")
 SVG_ATOM(letter_spacing, "letter-spacing")
 // defined above - SVG_ATOM(marker, "marker")
 SVG_ATOM(marker_end, "marker-end")
@@ -135,7 +148,9 @@
 SVG_ATOM(markerUnits, "markerUnits")
 SVG_ATOM(markerWidth, "markerWidth")
 SVG_ATOM(mask, "mask")
+SVG_ATOM(max, "max")
 SVG_ATOM(media, "media")
+SVG_ATOM(min, "min")
 SVG_ATOM(offset, "offset")
 SVG_ATOM(onclick, "onclick")
 SVG_ATOM(onmousedown, "onmousedown")
@@ -154,8 +169,11 @@
 SVG_ATOM(r, "r")
 SVG_ATOM(refX, "refX")
 SVG_ATOM(refY, "refY")
+SVG_ATOM(repeatCount, "repeatCount")
+SVG_ATOM(repeatDur, "repeatDur")
 SVG_ATOM(requiredExtensions, "requiredExtensions")
 SVG_ATOM(requiredFeatures, "requiredFeatures")
+SVG_ATOM(restart, "restart")
 SVG_ATOM(rx, "rx")
 SVG_ATOM(ry, "ry")
 SVG_ATOM(shape_rendering, "shape-rendering")
@@ -178,9 +196,11 @@
 SVG_ATOM(text_decoration, "text-decoration")
 SVG_ATOM(text_rendering, "text-rendering")
 // SVG_ATOM(title, "title") <-- already exists for the 'title' element
+SVG_ATOM(to, "to")
 SVG_ATOM(transform, "transform")
 SVG_ATOM(type, "type")
 SVG_ATOM(unicode_bidi, "unicode-bidi")
+SVG_ATOM(values, "values")
 SVG_ATOM(viewBox, "viewBox")
 SVG_ATOM(visibility, "visibility")
 SVG_ATOM(width, "width")
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.cpp
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.cpp	18 May 2005 11:22:48 -0000
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSVGClockValue.h"
+#include "prdtoa.h"
+#include "nsSVGValue.h"
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGClockValue class
+
+class nsSVGClockValue : public nsISVGClockValue,
+                        public nsSVGValue
+{
+protected:
+  friend nsresult NS_NewSVGClockValue(nsISVGClockValue** result,
+                                      const PRInt64& value);
+  nsSVGClockValue();
+  
+public:
+  // nsISupports interface:
+  NS_DECL_ISUPPORTS
+
+  // nsISVGValue interface:
+  NS_IMETHOD SetValueString(const nsAString& aValue);
+  NS_IMETHOD GetValueString(nsAString& aValue);
+
+  // nsISVGClockValue interface:
+  NS_IMETHOD GetValue(PRInt64& aValue);
+  NS_IMETHOD SetValue(const PRInt64& aValue);
+  
+protected:
+  PRInt64  mValue; // This could probably be a float or something (but note it
+                   // can't be PRTime as PRTime is unsigned and negative values
+                   // are valid). We should really have a typedef so we can
+                   // change this easily.
+  nsString mValueString;
+};
+
+//----------------------------------------------------------------------
+// implementation:
+
+nsresult
+NS_NewSVGClockValue(nsISVGClockValue** result, const PRInt64& value)
+{
+  *result = new nsSVGClockValue();
+  (*result)->SetValue(value);
+  if (!*result) return NS_ERROR_OUT_OF_MEMORY;
+  NS_ADDREF(*result);
+  return NS_OK;
+}
+
+nsSVGClockValue::nsSVGClockValue()
+    : mValue() // default constructor initialises to zero
+{}
+
+//----------------------------------------------------------------------
+// nsISupports methods:
+
+NS_IMPL_ADDREF(nsSVGClockValue)
+NS_IMPL_RELEASE(nsSVGClockValue)
+
+NS_INTERFACE_MAP_BEGIN(nsSVGClockValue)
+  NS_INTERFACE_MAP_ENTRY(nsISVGValue)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
+NS_INTERFACE_MAP_END
+
+//----------------------------------------------------------------------
+// nsISVGValue methods:
+
+NS_IMETHODIMP
+nsSVGClockValue::GetValueString(nsAString& aValue)
+{
+  aValue = mValueString;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGClockValue::SetValueString(const nsAString& aValue)
+{
+  nsresult rv = NS_OK;
+  
+  mValueString = aValue;
+  char *str = ToNewCString(aValue);
+
+  // XXX Parse clock values as defined in SVG spec 19.2.6. (For now we just
+  // take the first integer to be the no. of seconds. Implementing the full
+  // thing is easy.)
+
+  if (*str) {
+    char *rest;
+    PRFloat64 value = PR_strtod(str, &rest);
+    if (*rest && rest != str)
+    {
+      WillModify();
+      LL_D2L(mValue, value);
+      LL_MUL(mValue, mValue, PR_MSEC_PER_SEC);
+      DidModify();
+    }
+    else
+    {
+      rv = NS_ERROR_FAILURE;
+      // no number
+    }
+  }
+  nsMemory::Free(str);
+  return rv;
+}
+
+//----------------------------------------------------------------------
+// nsISVGClockValue methods:
+
+NS_IMETHODIMP
+nsSVGClockValue::GetValue(PRInt64& aValue)
+{
+  aValue = mValue;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGClockValue::SetValue(const PRInt64& aValue)
+{
+  mValue = aValue;
+  return NS_OK;
+}
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGClockValue.h	18 May 2005 11:22:48 -0000
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_SVGCLOCKVALUE_H__
+#define __NS_SVGCLOCKVALUE_H__
+
+#include "nsISVGClockValue.h"
+
+nsresult
+NS_NewSVGClockValue(nsISVGClockValue** result, const PRInt64& value);
+
+#endif //__NS_SVGCLOCKVALUE_H__
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp,v
retrieving revision 1.24
diff -u -r1.24 nsSVGElementFactory.cpp
--- /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp	25 Mar 2005 14:50:04 -0000	1.24
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGElementFactory.cpp	18 May 2005 11:22:48 -0000
@@ -96,6 +96,8 @@
 NS_NewSVGTitleElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
 nsresult
 NS_NewSVGClipPathElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
+nsresult
+NS_NewSVGAnimateElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
 
 static PRBool gSVGEnabled;
 static const char SVG_PREF_STR[] = "svg.enabled";
@@ -197,6 +199,8 @@
     return NS_NewSVGTitleElement(aResult, aNodeInfo);
   if (name == nsSVGAtoms::clipPath)
     return NS_NewSVGClipPathElement(aResult, aNodeInfo);
+  if (name == nsSVGAtoms::animate)
+    return NS_NewSVGAnimateElement(aResult, aNodeInfo);
 
   // if we don't know what to create, just create a standard xml element:
   return NS_NewXMLElement(aResult, aNodeInfo);
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp,v
retrieving revision 1.20
diff -u -r1.20 nsSVGLength.cpp
--- /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp	16 Feb 2005 18:39:59 -0000	1.20
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp	18 May 2005 11:22:51 -0000
@@ -40,71 +40,14 @@
 #include "nsSVGLength.h"
 #include "nsIDOMSVGMatrix.h"
 #include "nsSVGAtoms.h"
-#include "nsSVGValue.h"
 #include "nsTextFormatter.h"
 #include "prdtoa.h"
 #include "nsCRT.h"
 #include "nsSVGCoordCtx.h"
 #include "nsIDOMSVGNumber.h"
 #include "nsISVGValueUtils.h"
-#include "nsWeakReference.h"
 #include "nsContentUtils.h"
-
-////////////////////////////////////////////////////////////////////////
-// nsSVGLength class
-
-class nsSVGLength : public nsISVGLength,
-                    public nsSVGValue,
-                    public nsISVGValueObserver,
-                    public nsSupportsWeakReference
-{
-protected:
-  friend nsresult NS_NewSVGLength(nsISVGLength** result,
-                                  float value,
-                                  PRUint16 unit);
-
-  friend nsresult NS_NewSVGLength(nsISVGLength** result,
-                                  const nsAString &value);
-  
-  nsSVGLength(float value, PRUint16 unit);
-  nsSVGLength();
-  virtual ~nsSVGLength();
-
-public:
-  // nsISupports interface:
-  NS_DECL_ISUPPORTS
-
-  // nsIDOMSVGLength interface:
-  NS_DECL_NSIDOMSVGLENGTH
-
-  // nsISVGLength interface:
-  NS_IMETHOD SetContext(nsSVGCoordCtx* context);
-  
-  // nsISVGValue interface:
-  NS_IMETHOD SetValueString(const nsAString& aValue);
-  NS_IMETHOD GetValueString(nsAString& aValue);
-  
-  // nsISVGValueObserver interface:
-  NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
-                                     modificationType aModType);
-  NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
-                                     modificationType aModType);
-
-  // nsISupportsWeakReference
-  // implementation inherited from nsSupportsWeakReference
-  
-protected:
-  // implementation helpers:
-  float mmPerPixel();
-  float AxisLength();
-  PRBool IsValidUnitType(PRUint16 unit);
-  void MaybeAddAsObserver();
-  void MaybeRemoveAsObserver();
-  
-  float mValueInSpecifiedUnits;
-  PRUint16 mSpecifiedUnitType;
-  nsRefPtr<nsSVGCoordCtx> mContext;
-};
+#include "nsSVGTimelineManager.h"
 
 
 //----------------------------------------------------------------------
@@ -115,7 +58,7 @@
                 float value,
                 PRUint16 unit)
 {
-  *result = new nsSVGLength(value, unit);
+  *result = NS_STATIC_CAST(nsSVGLength__B__*, new nsSVGLength(value, unit));
   if (!*result)
     return NS_ERROR_OUT_OF_MEMORY;
   NS_ADDREF(*result);
@@ -136,7 +79,7 @@
     NS_RELEASE(pl);
     return rv;
   }
-  *result = pl;
+  *result = NS_STATIC_CAST(nsSVGLength__B__*, pl);
   return NS_OK;
 }  
 
@@ -164,11 +107,14 @@
 NS_IMPL_ADDREF(nsSVGLength)
 NS_IMPL_RELEASE(nsSVGLength)
 
+// XXX This is wrong. It causes Assert_NoQueryNeeded() from nsCOMPtr.h to fail
+// resulting in lots of assertions in the debug window.
+
 NS_INTERFACE_MAP_BEGIN(nsSVGLength)
   NS_INTERFACE_MAP_ENTRY(nsISVGValue)
   NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
-  NS_INTERFACE_MAP_ENTRY(nsISVGLength)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLength)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISVGLength, nsSVGLength__B__)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMSVGLength, nsSVGLength__B__)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGLength)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
@@ -219,9 +165,26 @@
   return NS_OK;
 }
 
-/* attribute float value; */
+/* attribute float value; (anim value) */
+NS_IMETHODIMP
+nsSVGLength__A__::GetValue(float *aValue)
+{
+  nsCOMPtr<nsISVGValue> val ( do_QueryInterface(this) );
+  if (nsSVGTimelineManager::IsAnimated(val))
+    return nsSVGTimelineManager::GetAnimValue(val, aValue);
+  else
+    return GetBaseValue(aValue);
+}
+
+/* attribute float value; (base value) */
+NS_IMETHODIMP
+nsSVGLength__B__::GetValue(float *aValue)
+{
+  return GetBaseValue(aValue);
+}
+
 NS_IMETHODIMP
-nsSVGLength::GetValue(float *aValue)
+nsSVGLength::GetBaseValue(float *aValue)
 {
   switch (mSpecifiedUnitType) {
     case SVG_LENGTHTYPE_NUMBER:
@@ -474,7 +437,8 @@
   if (observer_change)
     MaybeRemoveAsObserver();
   float valueInUserUnits;
-  GetValue(&valueInUserUnits);
+  // XXX This should be moved to the appropriate interface somehow
+  nsSVGLength__B__::GetValue(&valueInUserUnits);
   mSpecifiedUnitType = unitType;
   SetValue(valueInUserUnits);
   if (observer_change)
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGLength.h,v
retrieving revision 1.4
diff -u -r1.4 nsSVGLength.h
--- /cvsroot/mozilla/content/svg/content/src/nsSVGLength.h	17 Apr 2004 21:52:20 -0000	1.4
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGLength.h	18 May 2005 11:22:51 -0000
@@ -42,6 +42,10 @@
 #include "nsISVGLength.h"
 #include "nsAString.h"
 
+// Moved from nsSVGLength.cpp, move back eventually
+#include "nsSVGValue.h"
+#include "nsWeakReference.h"
+
 nsresult
 NS_NewSVGLength(nsISVGLength** result,
                 float value=0.0f,
@@ -56,4 +60,105 @@
 //                         nsIDOMSVGLength*  prototype);
 
 
+////////////////////////////////////////////////////////////////////////
+// These interfaces are used by nsSVGAnimatedLength to make the value
+// behave as either an animValue or a baseValue.
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGLength class (animated value)
+
+class nsSVGLength__A__ : public nsISVGLength
+{
+public:
+  NS_IMETHOD GetValue(float *aValue);
+};
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGLength class (base value)
+
+class nsSVGLength__B__ : public nsISVGLength
+{
+public:
+  NS_IMETHOD GetValue(float *aValue);
+};
+
+////////////////////////////////////////////////////////////////////////
+// This should definitely be hidden in nsSVGLength.cpp but at the moment
+// it is needed by nsSVGAnimatedLength. I think this is Scooter's area
+// anyway. :)
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGLength class
+
+class nsSVGValue;
+class nsISVGValueObserver;
+class nsSupportsWeakReference;
+
+class nsSVGLength : public nsSVGLength__B__, // : nsISVGLength
+                    public nsSVGLength__A__, // : nsISVGLength
+                    public nsSVGValue,
+                    public nsISVGValueObserver,
+                    public nsSupportsWeakReference
+{
+protected:
+  friend nsresult NS_NewSVGLength(nsISVGLength** result,
+                                  float value,
+                                  PRUint16 unit);
+
+  friend nsresult NS_NewSVGLength(nsISVGLength** result,
+                                  const nsAString &value);
+  
+  nsSVGLength(float value, PRUint16 unit);
+  nsSVGLength();
+  virtual ~nsSVGLength();
+
+public:
+  // nsISupports interface:
+  NS_DECL_ISUPPORTS
+
+  // nsIDOMSVGLength interface:
+  // Can't use NS_DECL_NSIDOMSVGLENGTH as we need to omit GetValue()
+  NS_IMETHOD GetUnitType(PRUint16 *aUnitType);
+  NS_IMETHOD SetValue(float aValue);
+  NS_IMETHOD GetValueInSpecifiedUnits(float *aValueInSpecifiedUnits);
+  NS_IMETHOD SetValueInSpecifiedUnits(float aValueInSpecifiedUnits);
+  NS_IMETHOD GetValueAsString(nsAString & aValueAsString);
+  NS_IMETHOD SetValueAsString(const nsAString & aValueAsString);
+  NS_IMETHOD NewValueSpecifiedUnits(PRUint16 unitType,
+                                    float valueInSpecifiedUnits);
+  NS_IMETHOD ConvertToSpecifiedUnits(PRUint16 unitType);
+  NS_IMETHOD GetTransformedValue(nsIDOMSVGMatrix *matrix, float *_retval); 
+
+  // nsISVGLength interface:
+  NS_IMETHOD SetContext(nsSVGCoordCtx* context);
+  
+  // nsISVGValue interface:
+  NS_IMETHOD SetValueString(const nsAString& aValue);
+  NS_IMETHOD GetValueString(nsAString& aValue);
+  
+  // nsISVGValueObserver interface:
+  NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
+                                     modificationType aModType);
+  NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
+                                     modificationType aModType);
+
+  // nsISupportsWeakReference
+  // implementation inherited from nsSupportsWeakReference
+  
+protected:
+  // nsISVGLength protected method:
+  NS_IMETHOD GetBaseValue(float* aValue);
+
+  // implementation helpers:
+  float mmPerPixel();
+  float AxisLength();
+  PRBool IsValidUnitType(PRUint16 unit);
+  void MaybeAddAsObserver();
+  void MaybeRemoveAsObserver();
+  
+  float mValueInSpecifiedUnits;
+  PRUint16 mSpecifiedUnitType;
+  nsRefPtr<nsSVGCoordCtx> mContext;
+};
+
 #endif //__NS_SVGLENGTH_H__
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGRectElement.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGRectElement.cpp,v
retrieving revision 1.12
diff -u -r1.12 nsSVGRectElement.cpp
--- /cvsroot/mozilla/content/svg/content/src/nsSVGRectElement.cpp	2 Feb 2005 20:31:50 -0000	1.12
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGRectElement.cpp	18 May 2005 11:22:52 -0000
@@ -45,11 +45,13 @@
 #include "nsCOMPtr.h"
 #include "nsISVGSVGElement.h"
 #include "nsSVGCoordCtxProvider.h"
+#include "nsISVGAnimationTarget.h"
 
 typedef nsSVGGraphicElement nsSVGRectElementBase;
 
 class nsSVGRectElement : public nsSVGRectElementBase,
-                         public nsIDOMSVGRectElement
+                         public nsIDOMSVGRectElement,
+                         public nsISVGAnimationTarget
 {
 protected:
   friend nsresult NS_NewSVGRectElement(nsIContent **aResult,
@@ -72,6 +74,9 @@
   // nsISVGContent specializations:
   virtual void ParentChainChanged();
 
+  // nsISVGAnimationTarget
+  virtual nsISVGValue* GetAnimatableAttribute(PRInt32 aNamespaceID, nsIAtom* aName);
+
 protected:
   
   nsCOMPtr<nsIDOMSVGAnimatedLength> mX;
@@ -98,6 +103,7 @@
   NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGRectElement)
+  NS_INTERFACE_MAP_ENTRY(nsISVGAnimationTarget)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGRectElement)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGRectElementBase)
 
@@ -334,4 +340,17 @@
   }
 
   // XXX call baseclass version to recurse into children?
-}  
+}
+
+
+//----------------------------------------------------------------------
+// nsISVGAnimationTarget methods
+
+// XXX This could be moved higher up the hierarchy (e.g. nsSVGElement
+// or nsSVGGraphicElement) and then overridden as necessary.
+
+nsISVGValue* nsSVGRectElement::GetAnimatableAttribute(PRInt32 aNamespaceID,
+                                                      nsIAtom* aName)
+{
+  return GetMappedAttribute(aNamespaceID, aName);
+}
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp,v
retrieving revision 1.50
diff -u -r1.50 nsSVGSVGElement.cpp
--- /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp	19 Feb 2005 10:31:24 -0000	1.50
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGSVGElement.cpp	18 May 2005 11:22:55 -0000
@@ -68,6 +68,7 @@
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsSVGEnum.h"
 #include "nsISVGChildFrame.h"
+#include "nsSVGTimelineManager.h"
 
 typedef nsSVGStylableElement nsSVGSVGElementBase;
 
@@ -103,6 +104,7 @@
   NS_IMETHOD SetParentCoordCtxProvider(nsSVGCoordCtxProvider *parentCtx);
   NS_IMETHOD GetCurrentScaleNumber(nsIDOMSVGNumber **aResult);
   NS_IMETHOD GetZoomAndPanEnum(nsISVGEnum **aResult);
+  NS_IMETHOD GetTimelineManager(nsISVGTimelineManager **aResult);
 
   // nsIStyledContent interface
   NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
@@ -116,6 +118,7 @@
 protected:
   // nsSVGElement overrides
   PRBool IsEventName(nsIAtom* aName);
+  void UnbindFromTree(PRBool aDeep, PRBool aNullParent);
 
   // implementation helpers:
   void GetScreenPosition(PRInt32 &x, PRInt32 &y);
@@ -132,6 +135,9 @@
   nsCOMPtr<nsISVGEnum>              mZoomAndPan;
   nsCOMPtr<nsIDOMSVGPoint>          mCurrentTranslate;
   nsCOMPtr<nsIDOMSVGNumber>         mCurrentScale;
+
+  // animation
+  nsCOMPtr<nsISVGTimelineManager>   mTimelineManager;
   
   PRInt32 mRedrawSuspendCount;
 };
@@ -1240,6 +1246,64 @@
   return NS_OK;
 }
 
+/*
+ * This really shouldn't be here. As roc suggested, the timeline manager could
+ * be per-document or per-view-manager-tree but for now we just create one when
+ * an animate element is created, i.e. we don't bother making it for unanimated
+ * svg documents.
+ */
+NS_IMETHODIMP
+nsSVGSVGElement::GetTimelineManager(nsISVGTimelineManager **aResult)
+{
+  nsresult rv;
+  *aResult = nsnull;
+
+  if (mTimelineManager)
+  {
+    *aResult = mTimelineManager;
+    NS_ADDREF(*aResult);
+  }
+  else
+  {
+    nsCOMPtr<nsISVGSVGElement> outerSVG = nsnull;
+    nsCOMPtr<nsIDOMSVGSVGElement> outerSVGDOM;
+
+    rv = GetOwnerSVGElement(getter_AddRefs(outerSVGDOM));
+    NS_ENSURE_SUCCESS(rv,rv);
+
+    if(outerSVGDOM)
+    {
+      /*
+       * If we were previously the outermost SVG element, we should remove our
+       * timeline manager.
+       */
+      if (mTimelineManager)
+        mTimelineManager = 0;
+
+      outerSVG = do_QueryInterface(outerSVGDOM);
+      rv = outerSVG->GetTimelineManager(aResult);
+      NS_ENSURE_SUCCESS(rv,rv);
+    }
+    else
+    {
+      /* _we_ are the outermost svg element */
+      nsCOMPtr<nsIEventListenerManager> manager;
+      rv = GetListenerManager(getter_AddRefs(manager));
+      NS_ENSURE_SUCCESS(rv,rv);
+
+      rv = NS_NewSVGTimelineManager(getter_AddRefs(mTimelineManager),
+                                    NS_STATIC_CAST(nsISVGSVGElement*,this),
+                                    manager);
+      NS_ENSURE_SUCCESS(rv,rv);
+
+      *aResult = mTimelineManager;
+      NS_ADDREF(*aResult);
+    }
+  }
+
+  return NS_OK;
+}
+
 //----------------------------------------------------------------------
 // nsIStyledContent methods
 
@@ -1321,6 +1385,17 @@
   return IsGraphicElementEventName(aName);
 }
 
+void
+nsSVGSVGElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
+{
+  if (mTimelineManager)
+  {
+    mTimelineManager->Shutdown();
+    mTimelineManager = nsnull;
+  }
+  nsSVGSVGElementBase::UnbindFromTree(aDeep, aNullParent);
+}
+
 //----------------------------------------------------------------------
 // implementation helpers
 void nsSVGSVGElement::GetScreenPosition(PRInt32 &x, PRInt32 &y)
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.cpp
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.cpp	18 May 2005 11:22:56 -0000
@@ -0,0 +1,329 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSVGTimelineManager.h"
+#include "nsGUIEvent.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIDOMEventListener.h"
+#include "nsIEventListenerManager.h"
+#include "nsISVGSVGElement.h"
+#include "nsWeakReference.h"
+#include "nsITimer.h"
+#include "nsISVGValue.h"
+#include "nsISVGAnimation.h"
+
+class nsSVGTimelineManagerImpl : public nsSVGTimelineManager,
+                                 public nsIDOMEventListener,
+                                 public nsSupportsWeakReference,
+                                 public nsITimerCallback
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITIMERCALLBACK
+  NS_DECL_NSIDOMEVENTLISTENER
+
+  // nsISVGTimelineManager
+  NS_IMETHOD RequestUpdate();
+  NS_IMETHOD Shutdown();
+
+protected:
+  nsSVGTimelineManagerImpl();
+  virtual ~nsSVGTimelineManagerImpl();
+
+  friend nsresult NS_NewSVGTimelineManager(nsISVGTimelineManager** aResult,
+                                           nsISVGSVGElement* svgElement,
+                                           nsIEventListenerManager* manager);
+
+  nsresult Init(nsISVGSVGElement *svgElement);
+
+  nsCOMPtr<nsITimer>         mTimer;
+  PRInt64                    mStartTime;
+};
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGTimelineManager implementation
+
+//----------------------------------------------------------------------
+// static members:
+
+// roc suggests this should use weak references and I agree. I previously
+// implemented this using an svg animation list class based on nsObserverList
+// but in order to support Alex's vtable idea I replaced it with this.
+nsInterfaceHashtable<nsISupportsHashKey, nsISVGAnimation>
+  nsSVGTimelineManager::mAnimationHash;
+
+//----------------------------------------------------------------------
+// static methods:
+
+NS_METHOD
+nsSVGTimelineManager::RegisterAnimation(nsISVGValue* value,
+                                        nsISVGAnimation* animation)
+{
+  if (!mAnimationHash.IsInitialized())
+    mAnimationHash.Init();
+
+  return mAnimationHash.Put(value, animation) ? NS_OK : NS_ERROR_FAILURE;
+}
+
+NS_METHOD
+nsSVGTimelineManager::UnregisterAnimation(nsISVGAnimation* animation)
+{
+  if (!mAnimationHash.IsInitialized())
+    mAnimationHash.Init();
+
+  mAnimationHash.Enumerate(&nsSVGTimelineManager::RemoveAnimation, animation);
+  return NS_OK;
+}
+
+PR_CALLBACK PLDHashOperator
+nsSVGTimelineManager::RemoveAnimation(nsISupportsHashKey::KeyType key,
+                                      nsCOMPtr<nsISVGAnimation>& animation,
+                                      void* userArg)
+{
+  nsISVGAnimation* targetAnimation = NS_STATIC_CAST(nsISVGAnimation*, userArg);
+  return (targetAnimation == animation) ? PL_DHASH_REMOVE : PL_DHASH_NEXT;
+}
+
+PRBool
+nsSVGTimelineManager::IsAnimated(nsISVGValue* const value)
+{
+  if (!mAnimationHash.IsInitialized())
+    mAnimationHash.Init();
+
+  return mAnimationHash.Get(value, nsnull);
+}
+
+NS_METHOD
+nsSVGTimelineManager::GetAnimValue(nsISVGValue* const value,
+                                   nsSVGAnimationValue* aValue)
+{
+  nsresult rv = NS_OK;
+
+  if (!mAnimationHash.IsInitialized())
+    mAnimationHash.Init();
+
+  nsCOMPtr<nsISVGAnimation> animation;
+  if (mAnimationHash.Get(value, getter_AddRefs(animation)))
+    animation->GetValue(aValue);
+  else
+    rv = NS_ERROR_FAILURE;
+  
+  return rv;
+}
+
+PR_CALLBACK PLDHashOperator
+nsSVGTimelineManager::StepAnimations(nsISupportsHashKey::KeyType key,
+                                     nsISVGAnimation* animation,
+                                     void* userArg)
+{
+  nsresult rv;
+  nsCOMPtr<nsISVGValue> value( do_QueryInterface(key, &rv) );
+  if (rv == NS_OK)
+  {
+    PRInt64* instant = NS_STATIC_CAST(PRInt64*, userArg);
+    animation->StepAnimation(*instant, value);
+  }
+  // else, cry
+
+  return PL_DHASH_NEXT;
+}
+
+////////////////////////////////////////////////////////////////////////
+// nsSVGTimelineManagerImpl implementation
+
+//----------------------------------------------------------------------
+// Constructors, destructors
+
+nsSVGTimelineManagerImpl::nsSVGTimelineManagerImpl() : mStartTime()
+{
+  if (!mAnimationHash.IsInitialized())
+    mAnimationHash.Init();
+}
+
+nsSVGTimelineManagerImpl::~nsSVGTimelineManagerImpl()
+{
+  if (mTimer)
+    mTimer->Cancel();
+}
+
+//----------------------------------------------------------------------
+// nsISupports methods:
+
+NS_IMPL_ISUPPORTS3(nsSVGTimelineManagerImpl,
+                   nsISVGTimelineManager,
+                   nsIDOMEventListener,
+                   nsISupportsWeakReference);
+
+//----------------------------------------------------------------------
+// nsIDOMListener methods:
+
+NS_METHOD
+nsSVGTimelineManagerImpl::HandleEvent(nsIDOMEvent* event)
+{
+  /*
+   * From the SVG spec, 19.2.2:
+   *
+   * SMIL Animation requires that the host language define the meaning for
+   * document begin and the document end. Since an 'svg' is sometimes the root
+   * of the XML document tree and other times can be a component of a parent XML
+   * grammar, the document begin for a given SVG document fragment is defined to
+   * be the exact time at which the 'svg' element's SVGLoad event is triggered.
+   * ...
+   * However, nested 'svg' elements within an SVG document do not
+   * constitute document fragments in this sense, and do not define a separate
+   * document begin; all times within the nested SVG fragment are relative to
+   * the document time defined for the root 'svg' element.
+   *
+   * My idea here was to register the timeline manager to receive the SVGLoad
+   * event. At the moment this won't work. SVGLoad events are only dispatched if
+   * there is an onLoad attribute in the document (see
+   * nsXMLContentSink::HandleEndElement). However, this may all change with
+   * tor's solution to #277955 (see also #252631). I'll wait to see how that's
+   * implemented first to see if we can hook in there somehow.
+   */
+
+  // XXX
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsITimerCallback methods
+
+NS_IMETHODIMP
+nsSVGTimelineManagerImpl::Notify(nsITimer *timer)
+{
+  NS_ASSERTION(mTimer == timer,
+               "nsSVGTimelineManagerImpl::Notify called with incorrect timer");
+
+  // It's probably more correct to use PRIntervalNow but I'm not sure if it
+  // will have sufficient range and is it's unsigned.
+  PRInt64 now;
+  LL_DIV(now, PR_Now(), PR_USEC_PER_MSEC);
+
+  // If this is the first time, record the document begin time
+  if (LL_IS_ZERO(mStartTime))
+    mStartTime = now;
+  
+  PRInt64 instant;
+  LL_SUB(instant, now, mStartTime);
+  mAnimationHash.EnumerateRead(&nsSVGTimelineManager::StepAnimations, &instant);
+
+  /*
+   * If this is the first time the callback has been called, setup the timer to
+   * repeat.
+   */
+  PRUint32 timerType;
+  mTimer->GetType(&timerType);
+  if (timerType == nsITimer::TYPE_ONE_SHOT)
+  {
+    mTimer->SetDelay(50);
+    mTimer->SetType(nsITimer::TYPE_REPEATING_SLACK);
+  }
+
+  return NS_OK;
+}
+
+
+//----------------------------------------------------------------------
+// nsISVGTimelineManager methods:
+
+NS_IMETHODIMP
+nsSVGTimelineManagerImpl::RequestUpdate()
+{
+  // XXX This is for when the client knows it's changed and wants to tell the
+  // timegraph.
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGTimelineManagerImpl::Shutdown()
+{
+  if (mTimer)
+  {
+    mTimer->Cancel();
+    mTimer = nsnull;
+  }
+    
+  return NS_OK;
+}
+
+//----------------------------------------------------------------------
+// nsSVGTimelineManagerImpl methods:
+
+nsresult
+nsSVGTimelineManagerImpl::Init(nsISVGSVGElement* svgElement)
+{
+  /*
+   * XXX This is just temporary until we correctly receive the onLoad event.
+   * We just set a timer to start in a few milliseconds to simulate it.
+   *
+   * The svgElement, I guess, will be needed to registering for the onLoad
+   * event.
+   */
+  mTimer = do_CreateInstance("@mozilla.org/timer;1");
+  if (!mTimer) return NS_ERROR_OUT_OF_MEMORY;
+
+  mTimer->InitWithCallback(NS_STATIC_CAST(nsITimerCallback*, this),
+                           100, nsITimer::TYPE_ONE_SHOT);
+
+  return NS_OK;
+}
+
+nsresult
+NS_NewSVGTimelineManager(nsISVGTimelineManager** aResult,
+                         nsISVGSVGElement* svgElement,
+                         nsIEventListenerManager* manager)
+{
+  nsresult rv;
+  *aResult = nsnull;
+  
+  nsSVGTimelineManagerImpl* timelineManager = new nsSVGTimelineManagerImpl();
+  if(!timelineManager) return NS_ERROR_OUT_OF_MEMORY;
+
+  rv = timelineManager->Init(svgElement);
+  NS_ENSURE_SUCCESS(rv,rv);
+
+  /* Register timeline manager to receive events */
+  // nsIDOMEventListener* listener = 
+  //   NS_STATIC_CAST(nsIDOMEventListener*,timelineManager);
+  // rv = manager->AddEventListenerByIID(listener,
+  //                                     nsISVGSVGElement::GetIID(),
+  //                                     NS_EVENT_BUBBLE_MASK);
+  // NS_ENSURE_SUCCESS(rv,rv);
+
+  NS_ADDREF(timelineManager);
+  *aResult = (nsISVGTimelineManager*) timelineManager;
+  
+  return NS_OK;
+}
+
Index: /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.h
===================================================================
RCS file: /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.h
diff -N /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/content/svg/content/src/nsSVGTimelineManager.h	18 May 2005 11:22:57 -0000
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __NS_SVGTIMELINEMANAGER_H__
+#define __NS_SVGTIMELINEMANAGER_H__
+
+#include "nsISVGTimelineManager.h"
+#include "nsInterfaceHashtable.h"
+
+/*
+ * I think if I tried I could have made this a little bit more messy. All this
+ * static stuff is just the easiest way to make the hash of animated values and
+ * animation objects global. Obviously it definitely shouldn't be like this. See
+ * comment in nsSVGSVGElement.cpp. The timeline manager (a.k.a. animation
+ * controller) should be per document or per view-manager-tree as suggested by
+ * roc.
+ */
+
+class nsISVGSVGElement;
+class nsIEventListenerManager;
+
+nsresult NS_NewSVGTimelineManager(nsISVGTimelineManager** aResult,
+                                  nsISVGSVGElement* svgElement,
+                                  nsIEventListenerManager* manager);
+
+class nsSVGTimelineManager : public nsISVGTimelineManager
+{
+public:
+  static NS_METHOD RegisterAnimation(nsISVGValue* value,
+                                     nsISVGAnimation* animation);
+  static NS_METHOD UnregisterAnimation(nsISVGAnimation* animation);
+  static NS_METHOD_(PRBool) IsAnimated(nsISVGValue* const value);
+  static NS_METHOD GetAnimValue(nsISVGValue* const value,
+                                nsSVGAnimationValue* aValue);
+
+protected:
+  nsSVGTimelineManager() { }
+
+  PR_STATIC_CALLBACK(PLDHashOperator)
+  StepAnimations(nsISupportsHashKey::KeyType key,
+                 nsISVGAnimation* animation,
+                 void* userArg);
+
+  PR_STATIC_CALLBACK(PLDHashOperator)
+  RemoveAnimation(nsISupportsHashKey::KeyType key,
+                  nsCOMPtr<nsISVGAnimation>& animation,
+                  void* userArg);
+
+  static
+  nsInterfaceHashtable<nsISupportsHashKey, nsISVGAnimation> mAnimationHash;
+};
+
+#endif // __NS_SVGTIMELINEMANAGER_H__
Index: /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h
===================================================================
RCS file: /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h,v
retrieving revision 1.64
diff -u -r1.64 nsIDOMClassInfo.h
--- /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h	11 May 2005 23:49:51 -0000	1.64
+++ /cvsroot/mozilla/dom/public/nsIDOMClassInfo.h	18 May 2005 11:23:01 -0000
@@ -249,6 +249,8 @@
   eDOMClassInfo_SVGDocument_id,
 
   // SVG element classes
+  eDOMClassInfo_SVGAnimateElement_id,
+  eDOMClassInfo_SVGAnimationElement_id,
   eDOMClassInfo_SVGCircleElement_id,
   eDOMClassInfo_SVGClipPathElement_id,
   eDOMClassInfo_SVGDefsElement_id,
Index: /cvsroot/mozilla/dom/public/idl/svg/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/dom/public/idl/svg/Makefile.in,v
retrieving revision 1.18
diff -u -r1.18 Makefile.in
--- /cvsroot/mozilla/dom/public/idl/svg/Makefile.in	23 Mar 2005 01:42:22 -0000	1.18
+++ /cvsroot/mozilla/dom/public/idl/svg/Makefile.in	18 May 2005 11:23:05 -0000
@@ -62,6 +62,8 @@
 		nsIDOMSVGAnimatedString.idl \
 		nsIDOMSVGAnimPresAspRatio.idl \
 		nsIDOMSVGAnimatedRect.idl \
+		nsIDOMSVGAnimateElement.idl \
+		nsIDOMSVGAnimationElement.idl \
 		nsIDOMSVGAnimTransformList.idl \
 		nsIDOMSVGCircleElement.idl \
 		nsIDOMSVGClipPathElement.idl \
Index: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl
===================================================================
RCS file: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl
diff -N /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimateElement.idl	18 May 2005 11:23:07 -0000
@@ -0,0 +1,43 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Crocodile Clips Ltd..
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMSVGAnimationElement.idl"
+
+[scriptable, uuid(0c4297e8-68d0-471d-a933-64132ccc5b97)]
+interface nsIDOMSVGAnimateElement : nsIDOMSVGAnimationElement {};
+
Index: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl
===================================================================
RCS file: /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl
diff -N /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ /cvsroot/mozilla/dom/public/idl/svg/nsIDOMSVGAnimationElement.idl	18 May 2005 11:23:07 -0000
@@ -0,0 +1,63 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Crocodile Clips Ltd..
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brian Birtles <birtles@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMSVGElement.idl"
+
+[scriptable, uuid(8f2ccf31-5544-4a9d-8927-ef35d242039e)]
+interface nsIDOMSVGAnimationElement
+  : nsIDOMSVGElement
+/*
+        The SVG DOM makes use of multiple interface inheritance.
+        Since XPCOM only supports single interface inheritance,
+        the best thing that we can do is to promise that whenever
+        an object implements _this_ interface it will also
+        implement the following interfaces. (We then have to QI to
+        hop between them.)
+        
+    nsIDOMSVGTests,
+    nsIDOMSVGExternalResourcesRequired,
+    smil::ElementTimeControl,
+    events::nsIDOMEventTarget
+*/
+{ 
+  readonly attribute nsIDOMSVGElement targetElement;
+  float getStartTime ( );
+  float getCurrentTime ( );
+  float getSimpleDuration ( );
+          // raises (nsIDOMDOMException)
+};
Index: /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp
===================================================================
RCS file: /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp,v
retrieving revision 1.278
diff -u -r1.278 nsDOMClassInfo.cpp
--- /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp	11 May 2005 23:49:52 -0000	1.278
+++ /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp	18 May 2005 11:23:30 -0000
@@ -324,6 +324,8 @@
 #include "nsIDOMSVGAnimPresAspRatio.h"
 #include "nsIDOMSVGAnimatedRect.h"
 #include "nsIDOMSVGAnimatedString.h"
+#include "nsIDOMSVGAnimateElement.h"
+#include "nsIDOMSVGAnimationElement.h"
 #include "nsIDOMSVGAnimTransformList.h"
 #include "nsIDOMSVGCircleElement.h"
 #include "nsIDOMSVGClipPathElement.h"
@@ -845,6 +847,10 @@
                            DOCUMENT_SCRIPTABLE_FLAGS)
 
   // SVG element classes
+  NS_DEFINE_CLASSINFO_DATA(SVGAnimateElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(SVGAnimationElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGCircleElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGClipPathElement, nsElementSH,
@@ -2343,6 +2349,17 @@
 
   // SVG element classes
 
+  DOM_CLASSINFO_MAP_BEGIN(SVGAnimateElement, nsIDOMSVGAnimateElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimateElement)
+    DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(SVGAnimationElement, nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimationElement)
+    DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(SVGCircleElement, nsIDOMSVGCircleElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGCircleElement)
     DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES
Index: /cvsroot/mozilla/layout/svg/base/src/nsSVGRectFrame.cpp
===================================================================
RCS file: /cvsroot/mozilla/layout/svg/base/src/nsSVGRectFrame.cpp,v
retrieving revision 1.9
diff -u -r1.9 nsSVGRectFrame.cpp
--- /cvsroot/mozilla/layout/svg/base/src/nsSVGRectFrame.cpp	19 Apr 2005 03:48:09 -0000	1.9
+++ /cvsroot/mozilla/layout/svg/base/src/nsSVGRectFrame.cpp	18 May 2005 11:23:31 -0000
@@ -133,6 +133,7 @@
 nsSVGRectFrame::InitSVG()
 {
   nsresult rv = nsSVGPathGeometryFrame::InitSVG();
+
   if (NS_FAILED(rv))
     return rv;
 
@@ -145,7 +146,12 @@
     NS_ASSERTION(mX, "no x");
     if (!mX)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mX);
+    /*
+     * We now observe the animated length, not the length as otherwise the check
+     * in DidModify... fails because the pointer to the baseValue gets passed in
+     * and not the pointer to the animValue.
+     */
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -157,7 +163,7 @@
     NS_ASSERTION(mY, "no y");
     if (!mY)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mY);
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -169,7 +175,7 @@
     NS_ASSERTION(mWidth, "no width");
     if (!mWidth)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mWidth);
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -180,7 +186,7 @@
     NS_ASSERTION(mHeight, "no height");
     if (!mHeight)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mHeight);
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -192,7 +198,7 @@
     NS_ASSERTION(mRx, "no rx");
     if (!mRx)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRx);
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -204,7 +210,7 @@
     NS_ASSERTION(mRy, "no ry");
     if (!mRy)
       return NS_ERROR_FAILURE;
-    nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRy);
+    nsCOMPtr<nsISVGValue> value = do_QueryInterface(length);
     if (value)
       value->AddObserver(this);
   }
@@ -219,7 +225,12 @@
 nsSVGRectFrame::DidModifySVGObservable(nsISVGValue* observable,
                                        nsISVGValue::modificationType aModType)
 {
-  nsCOMPtr<nsIDOMSVGLength> l = do_QueryInterface(observable);
+  /*
+   * Now we're observing the animated length, not the length itself.
+   */
+  nsCOMPtr<nsIDOMSVGAnimatedLength> a = do_QueryInterface(observable);
+  nsCOMPtr<nsIDOMSVGLength> l;
+  a->GetAnimVal(getter_AddRefs(l));
   if (l && (mX==l || mY==l || mWidth==l || mHeight==l || mRx==l || mRy==l)) {
     UpdateGraphic(nsISVGPathGeometrySource::UPDATEMASK_PATH);
     return NS_OK;
