Bug 824229 Part 7: Make nsSVGClipPathElement inherit from SVGTransformableElement to preserve existing behavior; move SVGGraphicsElement up to SVGTransformableElement r=longsonr
authorDavid Zbarsky <dzbarsky@gmail.com>
Sun, 06 Jan 2013 01:25:54 -0500
changeset 126880 257a5c4fd629f6fb7c77b7f844304ddaa38881f9
parent 126879 3b08c0ff70b190de871a852401d51ca74d04b0ff
child 126881 f51d9fb6b0917f9c01ede08de5cb510123b67101
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs824229
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 824229 Part 7: Make nsSVGClipPathElement inherit from SVGTransformableElement to preserve existing behavior; move SVGGraphicsElement up to SVGTransformableElement r=longsonr
content/svg/content/src/SVGGraphicsElement.cpp
content/svg/content/src/SVGGraphicsElement.h
content/svg/content/src/SVGTransformableElement.cpp
content/svg/content/src/SVGTransformableElement.h
content/svg/content/src/nsSVGClipPathElement.h
--- a/content/svg/content/src/SVGGraphicsElement.cpp
+++ b/content/svg/content/src/SVGGraphicsElement.cpp
@@ -1,28 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/Util.h"
-
 #include "mozilla/dom/SVGGraphicsElement.h"
-#include "nsSVGSVGElement.h"
-#include "DOMSVGAnimatedTransformList.h"
-#include "DOMSVGMatrix.h"
-#include "nsGkAtoms.h"
-#include "nsIDOMEventTarget.h"
-#include "nsIDOMMutationEvent.h"
-#include "nsIFrame.h"
-#include "nsISVGChildFrame.h"
-#include "nsSVGUtils.h"
-#include "nsError.h"
-#include "nsSVGRect.h"
-#include "nsContentUtils.h"
 #include "mozilla/dom/SVGGraphicsElementBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
 SVGGraphicsElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
 {
@@ -42,125 +28,10 @@ NS_INTERFACE_MAP_END_INHERITING(SVGGraph
 //----------------------------------------------------------------------
 // Implementation
 
 SVGGraphicsElement::SVGGraphicsElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGGraphicsElementBase(aNodeInfo)
 {
 }
 
-//----------------------------------------------------------------------
-// nsIContent methods
-
-NS_IMETHODIMP_(bool)
-SVGGraphicsElement::IsAttributeMapped(const nsIAtom* name) const
-{
-  static const MappedAttributeEntry* const map[] = {
-    sColorMap,
-    sFillStrokeMap,
-    sGraphicsMap
-  };
-
-  return FindAttributeDependence(name, map) ||
-    SVGGraphicsElementBase::IsAttributeMapped(name);
-}
-
-nsChangeHint
-SVGGraphicsElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                           int32_t aModType) const
-{
-  nsChangeHint retval =
-    SVGGraphicsElementBase::GetAttributeChangeHint(aAttribute, aModType);
-  if (aAttribute == nsGkAtoms::transform ||
-      aAttribute == nsGkAtoms::mozAnimateMotionDummyAttr) {
-    // We add nsChangeHint_UpdateOverflow so that nsFrame::UpdateOverflow()
-    // will be called on us and our ancestors.
-    nsIFrame* frame =
-      const_cast<SVGGraphicsElement*>(this)->GetPrimaryFrame();
-    if (!frame || (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
-      return retval; // no change
-    }
-    if (aModType == nsIDOMMutationEvent::ADDITION ||
-        aModType == nsIDOMMutationEvent::REMOVAL) {
-      // Reconstruct the frame tree to handle stacking context changes:
-      NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
-    } else {
-      NS_ABORT_IF_FALSE(aModType == nsIDOMMutationEvent::MODIFICATION,
-                        "Unknown modification type.");
-      // We just assume the old and new transforms are different.
-      NS_UpdateHint(retval, NS_CombineHint(nsChangeHint_UpdateOverflow,
-                                           nsChangeHint_UpdateTransformLayer));
-    }
-  }
-  return retval;
-}
-
-bool
-SVGGraphicsElement::IsEventAttributeName(nsIAtom* aName)
-{
-  return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement overrides
-
-gfxMatrix
-SVGGraphicsElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
-                                             TransformTypes aWhich) const
-{
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
-  gfxMatrix result(aMatrix);
-
-  if (aWhich == eChildToUserSpace) {
-    // We don't have anything to prepend.
-    // eChildToUserSpace is not the common case, which is why we return
-    // 'result' to benefit from NRVO rather than returning aMatrix before
-    // creating 'result'.
-    return result;
-  }
-
-  NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent,
-                    "Unknown TransformTypes");
-
-  // animateMotion's resulting transform is supposed to apply *on top of*
-  // any transformations from the |transform| attribute. So since we're
-  // PRE-multiplying, we need to apply the animateMotion transform *first*.
-  if (mAnimateMotionTransform) {
-    result.PreMultiply(*mAnimateMotionTransform);
-  }
-
-  if (mTransforms) {
-    result.PreMultiply(mTransforms->GetAnimValue().GetConsolidationMatrix());
-  }
-
-  return result;
-}
-
-const gfxMatrix*
-SVGGraphicsElement::GetAnimateMotionTransform() const
-{
-  return mAnimateMotionTransform.get();
-}
-
-void
-SVGGraphicsElement::SetAnimateMotionTransform(const gfxMatrix* aMatrix)
-{
-  if ((!aMatrix && !mAnimateMotionTransform) ||
-      (aMatrix && mAnimateMotionTransform && *aMatrix == *mAnimateMotionTransform)) {
-    return;
-  }
-  mAnimateMotionTransform = aMatrix ? new gfxMatrix(*aMatrix) : nullptr;
-  DidAnimateTransformList();
-}
-
-SVGAnimatedTransformList*
-SVGGraphicsElement::GetAnimatedTransformList(uint32_t aFlags)
-{
-  if (!mTransforms && (aFlags & DO_ALLOCATE)) {
-    mTransforms = new SVGAnimatedTransformList();
-  }
-  return mTransforms;
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGGraphicsElement.h
+++ b/content/svg/content/src/SVGGraphicsElement.h
@@ -1,19 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGGraphicsElement_h
 #define mozilla_dom_SVGGraphicsElement_h
 
-#include "gfxMatrix.h"
-#include "SVGTransformableElement.h"
-#include "SVGAnimatedTransformList.h"
+#include "mozilla/dom/SVGTransformableElement.h"
 #include "DOMSVGTests.h"
 
 #define MOZILLA_SVGGRAPHICSELEMENT_IID \
   { 0xe57b8fe5, 0x9088, 0x446e, \
     {0xa1, 0x87, 0xd1, 0xdb, 0xbb, 0x58, 0xce, 0xdc}}
 
 namespace mozilla {
 namespace dom {
@@ -28,46 +26,19 @@ protected:
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGGRAPHICSELEMENT_IID)
   NS_FORWARD_NSIDOMSVGLOCATABLE(SVGLocatableElement::)
   NS_FORWARD_NSIDOMSVGTRANSFORMABLE(SVGTransformableElement::)
 
-  // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-
-  nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                      int32_t aModType) const;
-
-
-  virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
-
-
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
-                      TransformTypes aWhich = eAllTransforms) const;
-  virtual const gfxMatrix* GetAnimateMotionTransform() const;
-  virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix);
-
-  virtual SVGAnimatedTransformList*
-    GetAnimatedTransformList(uint32_t aFlags = 0);
-  virtual nsIAtom* GetTransformListAttrName() const {
-    return nsGkAtoms::transform;
-  }
-
 protected:
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
 
-  // nsSVGElement overrides
-
-  nsAutoPtr<SVGAnimatedTransformList> mTransforms;
-
-  // XXX maybe move this to property table, to save space on un-animated elems?
-  nsAutoPtr<gfxMatrix> mAnimateMotionTransform;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(SVGGraphicsElement,
                               MOZILLA_SVGGRAPHICSELEMENT_IID)
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/svg/content/src/SVGTransformableElement.cpp
+++ b/content/svg/content/src/SVGTransformableElement.cpp
@@ -1,15 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "SVGTransformableElement.h"
+#include "mozilla/dom/SVGTransformableElement.h"
 #include "DOMSVGAnimatedTransformList.h"
+#include "nsIDOMMutationEvent.h"
+#include "nsIFrame.h"
+#include "nsSVGUtils.h"
+#include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGTransformableElement, SVGLocatableElement)
@@ -36,11 +40,126 @@ SVGTransformableElement::Transform()
 {
   // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList
   // to allocate the SVGAnimatedTransformList if it hasn't already done so:
   return DOMSVGAnimatedTransformList::GetDOMWrapper(
            GetAnimatedTransformList(DO_ALLOCATE), this).get();
 
 }
 
+//----------------------------------------------------------------------
+// nsIContent methods
+
+NS_IMETHODIMP_(bool)
+SVGTransformableElement::IsAttributeMapped(const nsIAtom* name) const
+{
+  static const MappedAttributeEntry* const map[] = {
+    sColorMap,
+    sFillStrokeMap,
+    sGraphicsMap
+  };
+
+  return FindAttributeDependence(name, map) ||
+    SVGLocatableElement::IsAttributeMapped(name);
+}
+
+nsChangeHint
+SVGTransformableElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                                int32_t aModType) const
+{
+  nsChangeHint retval =
+    SVGLocatableElement::GetAttributeChangeHint(aAttribute, aModType);
+  if (aAttribute == nsGkAtoms::transform ||
+      aAttribute == nsGkAtoms::mozAnimateMotionDummyAttr) {
+    // We add nsChangeHint_UpdateOverflow so that nsFrame::UpdateOverflow()
+    // will be called on us and our ancestors.
+    nsIFrame* frame =
+      const_cast<SVGTransformableElement*>(this)->GetPrimaryFrame();
+    if (!frame || (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
+      return retval; // no change
+    }
+    if (aModType == nsIDOMMutationEvent::ADDITION ||
+        aModType == nsIDOMMutationEvent::REMOVAL) {
+      // Reconstruct the frame tree to handle stacking context changes:
+      NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
+    } else {
+      NS_ABORT_IF_FALSE(aModType == nsIDOMMutationEvent::MODIFICATION,
+                        "Unknown modification type.");
+      // We just assume the old and new transforms are different.
+      NS_UpdateHint(retval, NS_CombineHint(nsChangeHint_UpdateOverflow,
+                                           nsChangeHint_UpdateTransformLayer));
+    }
+  }
+  return retval;
+}
+
+bool
+SVGTransformableElement::IsEventAttributeName(nsIAtom* aName)
+{
+  return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
+}
+
+//----------------------------------------------------------------------
+// nsSVGElement overrides
+
+gfxMatrix
+SVGTransformableElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+                                                  TransformTypes aWhich) const
+{
+  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
+                    "Skipping eUserSpaceToParent transforms makes no sense");
+
+  gfxMatrix result(aMatrix);
+
+  if (aWhich == eChildToUserSpace) {
+    // We don't have anything to prepend.
+    // eChildToUserSpace is not the common case, which is why we return
+    // 'result' to benefit from NRVO rather than returning aMatrix before
+    // creating 'result'.
+    return result;
+  }
+
+  NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent,
+                    "Unknown TransformTypes");
+
+  // animateMotion's resulting transform is supposed to apply *on top of*
+  // any transformations from the |transform| attribute. So since we're
+  // PRE-multiplying, we need to apply the animateMotion transform *first*.
+  if (mAnimateMotionTransform) {
+    result.PreMultiply(*mAnimateMotionTransform);
+  }
+
+  if (mTransforms) {
+    result.PreMultiply(mTransforms->GetAnimValue().GetConsolidationMatrix());
+  }
+
+  return result;
+}
+
+const gfxMatrix*
+SVGTransformableElement::GetAnimateMotionTransform() const
+{
+  return mAnimateMotionTransform.get();
+}
+
+void
+SVGTransformableElement::SetAnimateMotionTransform(const gfxMatrix* aMatrix)
+{
+  if ((!aMatrix && !mAnimateMotionTransform) ||
+      (aMatrix && mAnimateMotionTransform && *aMatrix == *mAnimateMotionTransform)) {
+    return;
+  }
+  mAnimateMotionTransform = aMatrix ? new gfxMatrix(*aMatrix) : nullptr;
+  DidAnimateTransformList();
+}
+
+SVGAnimatedTransformList*
+SVGTransformableElement::GetAnimatedTransformList(uint32_t aFlags)
+{
+  if (!mTransforms && (aFlags & DO_ALLOCATE)) {
+    mTransforms = new SVGAnimatedTransformList();
+  }
+  return mTransforms;
+}
+
 } // namespace dom
 } // namespace mozilla
 
--- a/content/svg/content/src/SVGTransformableElement.h
+++ b/content/svg/content/src/SVGTransformableElement.h
@@ -1,18 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SVGTransformableElement_h
 #define SVGTransformableElement_h
 
-#include "SVGLocatableElement.h"
+#include "mozilla/dom/SVGLocatableElement.h"
 #include "nsIDOMSVGTransformable.h"
+#include "gfxMatrix.h"
+#include "SVGAnimatedTransformList.h"
 
 #define MOZILLA_SVGTRANSFORMABLEELEMENT_IID \
   { 0x77888cba, 0x0b43, 0x4654, \
     {0x96, 0x3c, 0xf5, 0x50, 0xfc, 0xb5, 0x5e, 0x32}}
 
 namespace mozilla {
 class DOMSVGAnimatedTransformList;
 
@@ -26,16 +28,45 @@ public:
   virtual ~SVGTransformableElement() {}
 
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGTRANSFORMABLEELEMENT_IID)
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTRANSFORMABLE
 
   // WebIDL
   already_AddRefed<DOMSVGAnimatedTransformList> Transform();
+
+  // nsIContent interface
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+
+  nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                      int32_t aModType) const;
+
+
+  virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
+
+
+  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+                      TransformTypes aWhich = eAllTransforms) const;
+  virtual const gfxMatrix* GetAnimateMotionTransform() const;
+  virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix);
+
+  virtual SVGAnimatedTransformList*
+    GetAnimatedTransformList(uint32_t aFlags = 0);
+  virtual nsIAtom* GetTransformListAttrName() const {
+    return nsGkAtoms::transform;
+  }
+
+protected:
+  // nsSVGElement overrides
+
+  nsAutoPtr<SVGAnimatedTransformList> mTransforms;
+
+  // XXX maybe move this to property table, to save space on un-animated elems?
+  nsAutoPtr<gfxMatrix> mAnimateMotionTransform;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(SVGTransformableElement,
                               MOZILLA_SVGTRANSFORMABLEELEMENT_IID)
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/svg/content/src/nsSVGClipPathElement.h
+++ b/content/svg/content/src/nsSVGClipPathElement.h
@@ -4,19 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGCLIPPATHELEMENT_H__
 #define __NS_SVGCLIPPATHELEMENT_H__
 
 #include "nsIDOMSVGClipPathElement.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEnum.h"
-#include "SVGGraphicsElement.h"
+#include "mozilla/dom/SVGTransformableElement.h"
 
-typedef mozilla::dom::SVGGraphicsElement nsSVGClipPathElementBase;
+typedef mozilla::dom::SVGTransformableElement nsSVGClipPathElementBase;
 
 class nsSVGClipPathElement : public nsSVGClipPathElementBase,
                              public nsIDOMSVGClipPathElement,
                              public nsIDOMSVGUnitTypes
 {
   friend class nsSVGClipPathFrame;
 
 protected:
@@ -29,16 +29,18 @@ public:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGCLIPPATHELEMENT
 
   // xxx I wish we could use virtual inheritance
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGClipPathElementBase::)
+  NS_FORWARD_NSIDOMSVGLOCATABLE(mozilla::dom::SVGLocatableElement::)
+  NS_FORWARD_NSIDOMSVGTRANSFORMABLE(mozilla::dom::SVGTransformableElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected: