Bug 470653 - nsSVGElement::AfterSetAttr should probably use insertionParent, not insertionParent of the bindingParent. r+sr=roc
authorRobert Longson <longsonr@gmail.com>
Mon, 09 Mar 2009 13:14:35 +0000
changeset 25867 f8c83e876d37715e1f94860fc5f56a61592b2b10
parent 25866 5b3f64e0c7214928433e8f14472c0eecdd2305aa
child 25868 3155b813495994acd68d48825832b0171c8411c5
push idunknown
push userunknown
push dateunknown
bugs470653
milestone1.9.2a1pre
Bug 470653 - nsSVGElement::AfterSetAttr should probably use insertionParent, not insertionParent of the bindingParent. r+sr=roc
content/svg/content/src/nsSVGAnimationElement.cpp
content/svg/content/src/nsSVGAnimationElement.h
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGGraphicElement.cpp
content/svg/content/src/nsSVGSVGElement.cpp
layout/svg/base/src/nsSVGUtils.cpp
layout/svg/base/src/nsSVGUtils.h
--- a/content/svg/content/src/nsSVGAnimationElement.cpp
+++ b/content/svg/content/src/nsSVGAnimationElement.cpp
@@ -37,17 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsSVGAnimationElement.h"
 #include "nsSVGSVGElement.h"
 #include "nsSMILTimeContainer.h"
 #include "nsSMILAnimationController.h"
 #include "nsSMILAnimationFunction.h"
 #include "nsISMILAttr.h"
-#include "nsBindingManager.h"
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
 
 NS_INTERFACE_MAP_BEGIN(nsSVGAnimationElement)
@@ -107,17 +106,17 @@ nsSVGAnimationElement::GetTargetElementC
     // the existing target's ID might've changed, or another element
     // with the same ID might've been inserted earlier in the DOM tree.
     NS_NOTYETIMPLEMENTED("nsSVGAnimationElement::GetTargetElementContent for "
                          "xlink:href-targeted animations");
     return nsnull;
   }
 
   // No "xlink:href" attribute --> target is my parent.
-  return GetParentElement();
+  return nsSVGUtils::GetParentElement(this);
 }
 
 nsIAtom*
 nsSVGAnimationElement::GetTargetAttributeName() const
 {
   const nsAttrValue* nameAttr
     = mAttrsAndChildren.GetAttr(nsGkAtoms::attributeName);
 
@@ -356,38 +355,16 @@ nsSVGAnimationElement::GetTimeContainer(
     nsSVGSVGElement *ownerSVG =
       static_cast<nsSVGSVGElement*>(ownerDOMSVG.get());
     result = ownerSVG->GetTimedDocumentRoot();
   }
 
   return result;
 }
 
-nsIContent*
-nsSVGAnimationElement::GetParentElement()
-{
-  nsCOMPtr<nsIContent> result;
-  nsBindingManager*   bindingManager = nsnull;
-  nsIDocument*        ownerDoc = GetOwnerDoc();
-
-  if (ownerDoc)
-    bindingManager = ownerDoc->BindingManager();
-
-  if (bindingManager)
-    // we have a binding manager -- do we have an anonymous parent?
-    result = bindingManager->GetInsertionParent(this);
-
-  if (!result)
-    // if we didn't find an anonymous parent, use the explicit one,
-    // whether it's null or not...
-    result = GetParent();
-
-  return result;
-}
-
 // nsIDOMElementTimeControl
 /* void beginElement (); */
 NS_IMETHODIMP
 nsSVGAnimationElement::BeginElement(void)
 {
   return BeginElementAt(0.f);
 }
 
--- a/content/svg/content/src/nsSVGAnimationElement.h
+++ b/content/svg/content/src/nsSVGAnimationElement.h
@@ -86,16 +86,13 @@ public:
   virtual const nsAttrValue* GetAnimAttr(nsIAtom* aName) const;
   virtual nsIContent* GetTargetElementContent();
   virtual nsIAtom* GetTargetAttributeName() const;
   virtual nsSMILTargetAttrType GetTargetAttributeType() const;
   virtual nsSMILTimedElement& TimedElement();
   virtual nsSMILTimeContainer* GetTimeContainer();
 
 protected:
-  // Implementation helpers
-  nsIContent* GetParentElement();
-
   nsSMILTimedElement   mTimedElement;
   nsSMILTimeContainer* mTimedDocumentRoot;
 };
 
 #endif // NS_SVGANIMATIONELEMENT_H_
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -257,32 +257,18 @@ nsSVGElement::AfterSetAttr(PRInt32 aName
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (aNamespaceID == kNameSpaceID_None &&
       (aName == nsGkAtoms::requiredFeatures ||
        aName == nsGkAtoms::requiredExtensions ||
        aName == nsGkAtoms::systemLanguage)) {
 
-    nsIContent* parent = nsnull;
+    nsIContent* parent = nsSVGUtils::GetParentElement(this);
   
-    nsIContent* bindingParent = GetBindingParent();
-    if (bindingParent) {
-      nsIDocument* doc = bindingParent->GetOwnerDoc();
-      if (doc) {
-        parent = doc->BindingManager()->GetInsertionParent(bindingParent);
-      }
-    }
-
-    if (!parent) {
-      // if we didn't find an anonymous parent, use the explicit one,
-      // whether it's null or not...
-      parent = GetParent();
-    }
-
     if (parent &&
         parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) {
       static_cast<nsSVGSwitchElement*>(parent)->MaybeInvalidate();
     }
   }
 
   return nsSVGElementBase::AfterSetAttr(aNamespaceID, aName, aValue, aNotify);
 }
@@ -908,61 +894,31 @@ NS_IMETHODIMP nsSVGElement::SetId(const 
 }
 
 /* readonly attribute nsIDOMSVGSVGElement ownerSVGElement; */
 NS_IMETHODIMP
 nsSVGElement::GetOwnerSVGElement(nsIDOMSVGSVGElement * *aOwnerSVGElement)
 {
   *aOwnerSVGElement = nsnull;
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the binding that gives us our anonymous parent.
-  // That's the binding manager for the document we actually belong to, which
-  // is our owner doc.
-  nsIDocument* ownerDoc = GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
-  nsIContent* parent = nsnull;
+  nsIContent* parent = nsSVGUtils::GetParentElement(this);
   
-  if (bindingManager) {
-    // we have a binding manager -- do we have an anonymous parent?
-    parent = bindingManager->GetInsertionParent(this);
-  }
-
-  if (!parent) {
-    // if we didn't find an anonymous parent, use the explicit one,
-    // whether it's null or not...
-    parent = GetParent();
-  }
-
   while (parent && parent->GetNameSpaceID() == kNameSpaceID_SVG) {
     nsIAtom* tag = parent->Tag();
     if (tag == nsGkAtoms::foreignObject) {
       // SVG in a foreignObject must have its own <svg> (nsSVGOuterSVGFrame).
       // Leave *aOwnerSVGElement nulled out, but don't throw.
       return NS_OK;
     }
     if (tag == nsGkAtoms::svg) {
       *aOwnerSVGElement = static_cast<nsSVGSVGElement*>(parent);
       NS_ADDREF(*aOwnerSVGElement);
       return NS_OK;
     }
-    nsIContent* next = nsnull;
-
-    if (bindingManager) {
-      next = bindingManager->GetInsertionParent(parent);
-    }
-    if (!next) {
-      // no anonymous parent, so use explicit one
-      next = parent->GetParent();
-    }
-    
+    nsIContent* next = nsSVGUtils::GetParentElement(parent);
     parent = next;
   }
 
   // we don't have a parent SVG element...
 
   // are _we_ the outermost SVG element? If yes, return nsnull, but don't fail
   if (Tag() == nsGkAtoms::svg) {
     return NS_OK;
--- a/content/svg/content/src/nsSVGGraphicElement.cpp
+++ b/content/svg/content/src/nsSVGGraphicElement.cpp
@@ -38,17 +38,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsSVGGraphicElement.h"
 #include "nsSVGTransformList.h"
 #include "nsSVGAnimatedTransformList.h"
 #include "nsGkAtoms.h"
 #include "nsSVGMatrix.h"
 #include "nsIDOMEventTarget.h"
-#include "nsBindingManager.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsIDOMSVGPoint.h"
 #include "nsSVGUtils.h"
 #include "nsDOMError.h"
 
 //----------------------------------------------------------------------
 // nsISupports methods
@@ -141,46 +140,27 @@ NS_IMETHODIMP nsSVGGraphicElement::GetCT
   *_retval = nsnull;
 
   nsIDocument* currentDoc = GetCurrentDoc();
   if (currentDoc) {
     // Flush all pending notifications so that our frames are uptodate
     currentDoc->FlushPendingNotifications(Flush_Layout);
   }
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the binding that gives us our anonymous parent.
-  // That's the binding manager for the document we actually belong to, which
-  // is our owner doc.
-  nsIDocument* ownerDoc = GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
-  nsIContent* parent = nsnull;
-  nsCOMPtr<nsIDOMSVGMatrix> parentCTM;
-
-  if (bindingManager) {
-    // check for an anonymous parent first
-    parent = bindingManager->GetInsertionParent(this);
-  }
-  if (!parent) {
-    // if we didn't find an anonymous parent, use the explicit one
-    parent = GetParent();
-  }
+  nsIContent* parent = nsSVGUtils::GetParentElement(this);
 
   nsCOMPtr<nsIDOMSVGLocatable> locatableElement = do_QueryInterface(parent);
   if (!locatableElement) {
     // we don't have an SVGLocatable parent so we aren't even rendered
     NS_WARNING("SVGGraphicElement without an SVGLocatable parent");
     return NS_ERROR_FAILURE;
   }
 
   // get our parent's CTM
+  nsCOMPtr<nsIDOMSVGMatrix> parentCTM;
   rv = locatableElement->GetCTM(getter_AddRefs(parentCTM));
   if (NS_FAILED(rv)) return rv;
 
   return AppendLocalTransform(parentCTM, _retval);
 }
 
 /* nsIDOMSVGMatrix getScreenCTM (); */
 NS_IMETHODIMP nsSVGGraphicElement::GetScreenCTM(nsIDOMSVGMatrix **_retval)
@@ -189,46 +169,27 @@ NS_IMETHODIMP nsSVGGraphicElement::GetSc
   *_retval = nsnull;
 
   nsIDocument* currentDoc = GetCurrentDoc();
   if (currentDoc) {
     // Flush all pending notifications so that our frames are uptodate
     currentDoc->FlushPendingNotifications(Flush_Layout);
   }
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the binding that gives us our anonymous parent.
-  // That's the binding manager for the document we actually belong to, which
-  // is our owner doc.
-  nsIDocument* ownerDoc = GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
-  nsIContent* parent = nsnull;
-  nsCOMPtr<nsIDOMSVGMatrix> parentScreenCTM;
-
-  if (bindingManager) {
-    // check for an anonymous parent first
-    parent = bindingManager->GetInsertionParent(this);
-  }
-  if (!parent) {
-    // if we didn't find an anonymous parent, use the explicit one
-    parent = GetParent();
-  }
+  nsIContent* parent = nsSVGUtils::GetParentElement(this);
 
   nsCOMPtr<nsIDOMSVGLocatable> locatableElement = do_QueryInterface(parent);
   if (!locatableElement) {
     // we don't have an SVGLocatable parent so we aren't even rendered
     NS_WARNING("SVGGraphicElement without an SVGLocatable parent");
     return NS_ERROR_FAILURE;
   }
 
   // get our parent's "screen" CTM
+  nsCOMPtr<nsIDOMSVGMatrix> parentScreenCTM;
   rv = locatableElement->GetScreenCTM(getter_AddRefs(parentScreenCTM));
   if (NS_FAILED(rv)) return rv;
 
   return AppendLocalTransform(parentScreenCTM, _retval);
 }
 
 /* nsIDOMSVGMatrix getTransformToElement (in nsIDOMSVGElement element); */
 NS_IMETHODIMP nsSVGGraphicElement::GetTransformToElement(nsIDOMSVGElement *element, nsIDOMSVGMatrix **_retval)
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -45,17 +45,16 @@
 #include "nsIPresShell.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsSVGMatrix.h"
 #include "nsSVGPoint.h"
 #include "nsSVGTransform.h"
 #include "nsIDOMEventTarget.h"
-#include "nsBindingManager.h"
 #include "nsIFrame.h"
 #include "nsISVGSVGFrame.h" //XXX
 #include "nsSVGNumber.h"
 #include "nsSVGRect.h"
 #include "nsISVGValueUtils.h"
 #include "nsDOMError.h"
 #include "nsISVGChildFrame.h"
 #include "nsGUIEvent.h"
@@ -770,41 +769,23 @@ nsSVGSVGElement::GetCTM(nsIDOMSVGMatrix 
   nsIDocument* currentDoc = GetCurrentDoc();
   if (currentDoc) {
     // Flush all pending notifications so that our frames are uptodate
     currentDoc->FlushPendingNotifications(Flush_Layout);
   }
 
   // first try to get the "screen" CTM of our nearest SVG ancestor
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the bindings that gives us our anonymous
-  // ancestors. That's the binding manager for the document we actually belong
-  // to, which is our owner doc.
-  nsIDocument* ownerDoc = GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
   nsCOMPtr<nsIContent> element = this;
   nsCOMPtr<nsIContent> ancestor;
   unsigned short ancestorCount = 0;
   nsCOMPtr<nsIDOMSVGMatrix> ancestorCTM;
 
   while (1) {
-    ancestor = nsnull;
-    if (bindingManager) {
-      // check for an anonymous ancestor first
-      ancestor = bindingManager->GetInsertionParent(element);
-    }
-    if (!ancestor) {
-      // if we didn't find an anonymous ancestor, use the explicit one
-      ancestor = element->GetParent();
-    }
+    ancestor = nsSVGUtils::GetParentElement(element);
     if (!ancestor) {
       // reached the top of our parent chain without finding an SVG ancestor
       break;
     }
 
     nsSVGSVGElement *viewportElement = QI_AND_CAST_TO_NSSVGSVGELEMENT(ancestor);
     if (viewportElement) {
       rv = viewportElement->GetViewboxToViewportTransform(getter_AddRefs(ancestorCTM));
@@ -892,41 +873,23 @@ nsSVGSVGElement::GetScreenCTM(nsIDOMSVGM
   nsIDocument* currentDoc = GetCurrentDoc();
   if (currentDoc) {
     // Flush all pending notifications so that our frames are uptodate
     currentDoc->FlushPendingNotifications(Flush_Layout);
   }
 
   // first try to get the "screen" CTM of our nearest SVG ancestor
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the bindings that gives us our anonymous
-  // ancestors. That's the binding manager for the document we actually belong
-  // to, which is our owner doc.
-  nsIDocument* ownerDoc = GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
   nsCOMPtr<nsIContent> element = this;
   nsCOMPtr<nsIContent> ancestor;
   unsigned short ancestorCount = 0;
   nsCOMPtr<nsIDOMSVGMatrix> ancestorScreenCTM;
 
   while (1) {
-    ancestor = nsnull;
-    if (bindingManager) {
-      // check for an anonymous ancestor first
-      ancestor = bindingManager->GetInsertionParent(element);
-    }
-    if (!ancestor) {
-      // if we didn't find an anonymous ancestor, use the explicit one
-      ancestor = element->GetParent();
-    }
+    ancestor = nsSVGUtils::GetParentElement(element);
     if (!ancestor) {
       // reached the top of our parent chain without finding an SVG ancestor
       break;
     }
 
     nsCOMPtr<nsIDOMSVGLocatable> locatableElement = do_QueryInterface(ancestor);
     if (locatableElement) {
       rv = locatableElement->GetScreenCTM(getter_AddRefs(ancestorScreenCTM));
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -203,16 +203,39 @@ GetFrameForContent(nsIContent* aContent)
 
   nsIDocument *doc = aContent->GetCurrentDoc();
   if (!doc)
     return nsnull;
 
   return nsGenericElement::GetPrimaryFrameFor(aContent, doc);
 }
 
+nsIContent*
+nsSVGUtils::GetParentElement(nsIContent *aContent)
+{
+  // XXXbz I _think_ this is right.  We want to be using the binding manager
+  // that would have attached the binding that gives us our anonymous parent.
+  // That's the binding manager for the document we actually belong to, which
+  // is our owner doc.
+  nsIDocument* ownerDoc = aContent->GetOwnerDoc();
+  nsBindingManager* bindingManager =
+    ownerDoc ? ownerDoc->BindingManager() : nsnull;
+
+  if (bindingManager) {
+    // if we have a binding manager -- do we have an anonymous parent?
+    nsIContent *result = bindingManager->GetInsertionParent(aContent);
+    if (result) {
+      return result;
+    }
+  }
+
+  // otherewise use the explicit one, whether it's null or not...
+  return aContent->GetParent();
+}
+
 float
 nsSVGUtils::GetFontSize(nsIContent *aContent)
 {
   nsIFrame* frame = GetFrameForContent(aContent);
   if (!frame) {
     NS_WARNING("no frame in GetFontSize()");
     return 1.0f;
   }
@@ -381,41 +404,23 @@ nsSVGUtils::CoordToFloat(nsPresContext *
 }
 
 nsresult
 nsSVGUtils::GetNearestViewportElement(nsIContent *aContent,
                                       nsIDOMSVGElement * *aNearestViewportElement)
 {
   *aNearestViewportElement = nsnull;
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the bindings that gives us our anonymous
-  // ancestors. That's the binding manager for the document we actually belong
-  // to, which is our owner doc.
-  nsIDocument* ownerDoc = aContent->GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
   nsCOMPtr<nsIContent> element = aContent;
   nsCOMPtr<nsIContent> ancestor;
   unsigned short ancestorCount = 0;
 
   while (1) {
 
-    ancestor = nsnull;
-    if (bindingManager) {
-      // check for an anonymous ancestor first
-      ancestor = bindingManager->GetInsertionParent(element);
-    }
-    if (!ancestor) {
-      // if we didn't find an anonymous ancestor, use the explicit one
-      ancestor = element->GetParent();
-    }
+    ancestor = GetParentElement(element);
 
     nsCOMPtr<nsIDOMSVGFitToViewBox> fitToViewBox = do_QueryInterface(element);
 
     if (fitToViewBox && (ancestor || ancestorCount)) {
       // right interface and not the outermost SVG element
       nsCOMPtr<nsIDOMSVGElement> SVGElement = do_QueryInterface(element);
       SVGElement.swap(*aNearestViewportElement);
       return NS_OK;
@@ -434,42 +439,24 @@ nsSVGUtils::GetNearestViewportElement(ns
 }
 
 nsresult
 nsSVGUtils::GetFarthestViewportElement(nsIContent *aContent,
                                        nsIDOMSVGElement * *aFarthestViewportElement)
 {
   *aFarthestViewportElement = nsnull;
 
-  nsBindingManager *bindingManager = nsnull;
-  // XXXbz I _think_ this is right.  We want to be using the binding manager
-  // that would have attached the bindings that gives us our anonymous
-  // ancestors. That's the binding manager for the document we actually belong
-  // to, which is our owner doc.
-  nsIDocument* ownerDoc = aContent->GetOwnerDoc();
-  if (ownerDoc) {
-    bindingManager = ownerDoc->BindingManager();
-  }
-
   nsCOMPtr<nsIContent> element = aContent;
   nsCOMPtr<nsIContent> ancestor;
   nsCOMPtr<nsIDOMSVGElement> SVGElement;
   unsigned short ancestorCount = 0;
 
   while (1) {
 
-    ancestor = nsnull;
-    if (bindingManager) {
-      // check for an anonymous ancestor first
-      ancestor = bindingManager->GetInsertionParent(element);
-    }
-    if (!ancestor) {
-      // if we didn't find an anonymous ancestor, use the explicit one
-      ancestor = element->GetParent();
-    }
+    ancestor = GetParentElement(element);
 
     nsCOMPtr<nsIDOMSVGFitToViewBox> fitToViewBox = do_QueryInterface(element);
 
     if (fitToViewBox) {
       // right interface
       SVGElement = do_QueryInterface(element);
     }
 
--- a/layout/svg/base/src/nsSVGUtils.h
+++ b/layout/svg/base/src/nsSVGUtils.h
@@ -180,16 +180,21 @@ public:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGFilterProperty, NS_ISVGFILTERPROPERTY_IID)
 
 class nsSVGUtils
 {
 public:
   /*
+   * Get the parent element of an nsIContent
+   */
+  static nsIContent *GetParentElement(nsIContent *aContent);
+
+  /*
    * Get a font-size (em) of an nsIContent
    */
   static float GetFontSize(nsIContent *aContent);
   static float GetFontSize(nsIFrame *aFrame);
   /*
    * Get an x-height of of an nsIContent
    */
   static float GetFontXHeight(nsIContent *aContent);