Bug 1245751 - Part 11: Allow href without xlink on SVG Animation elements. draft
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 07 Jul 2016 15:43:37 +0800
changeset 407862 bc5c68ea10fb547099dd973e9799e7868f20a429
parent 407861 6b2613479084dd04277569a7055f70a747eb4973
child 407863 8250770d3bb22123a3a881fd8c2fa9a42841b1a5
push id28064
push userbmo:boris.chiou@gmail.com
push dateWed, 31 Aug 2016 04:26:14 +0000
bugs1245751
milestone51.0a1
Bug 1245751 - Part 11: Allow href without xlink on SVG Animation elements. MozReview-Commit-ID: LJnJgHipDMP
dom/svg/SVGAnimationElement.cpp
--- a/dom/svg/SVGAnimationElement.cpp
+++ b/dom/svg/SVGAnimationElement.cpp
@@ -76,24 +76,25 @@ bool
 SVGAnimationElement::HasAnimAttr(nsIAtom* aAttName) const
 {
   return HasAttr(kNameSpaceID_None, aAttName);
 }
 
 Element*
 SVGAnimationElement::GetTargetElementContent()
 {
-  if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
+  if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href) ||
+      HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
     return mHrefTarget.get();
   }
   MOZ_ASSERT(!mHrefTarget.get(),
-             "We shouldn't have an xlink:href target "
-             "if we don't have an xlink:href attribute");
+             "We shouldn't have a href target "
+             "if we don't have an xlink:href or href attribute");
 
-  // No "xlink:href" attribute --> I should target my parent.
+  // No "href" or "xlink:href" attribute --> I should target my parent.
   nsIContent* parent = GetFlattenedTreeParent();
   return parent && parent->IsElement() ? parent->AsElement() : nullptr;
 }
 
 bool
 SVGAnimationElement::GetTargetAttributeName(int32_t *aNamespaceID,
                                             nsIAtom **aLocalName) const
 {
@@ -211,18 +212,20 @@ SVGAnimationElement::BindToTree(nsIDocum
   }
 
   // Add myself to the animation controller's master set of animation elements.
   if (aDocument) {
     nsSMILAnimationController *controller = aDocument->GetAnimationController();
     if (controller) {
       controller->RegisterAnimationElement(this);
     }
-    const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href,
-                                                        kNameSpaceID_XLink);
+    const nsAttrValue* href =
+      HasAttr(kNameSpaceID_None, nsGkAtoms::href)
+      ? mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_None)
+      : mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
     if (href) {
       nsAutoString hrefStr;
       href->ToString(hrefStr);
 
       // Pass in |aParent| instead of |this| -- first argument is only used
       // for a call to GetComposedDoc(), and |this| might not have a current
       // document yet.
       UpdateHrefTarget(aParent, hrefStr);
@@ -304,23 +307,44 @@ SVGAnimationElement::AfterSetAttr(int32_
 
   if (SVGTests::IsConditionalProcessingAttribute(aName)) {
     bool isDisabled = !SVGTests::PassesConditionalProcessingTests();
     if (mTimedElement.SetIsDisabled(isDisabled)) {
       AnimationNeedsResample();
     }
   }
 
-  if (aNamespaceID != kNameSpaceID_XLink || aName != nsGkAtoms::href)
+  if (!((aNamespaceID == kNameSpaceID_None ||
+         aNamespaceID == kNameSpaceID_XLink) &&
+        aName == nsGkAtoms::href)) {
     return rv;
+  }
 
   if (!aValue) {
-    mHrefTarget.Unlink();
-    AnimationTargetChanged();
-  } else if (IsInUncomposedDoc()) {
+    if (aNamespaceID == kNameSpaceID_None) {
+      mHrefTarget.Unlink();
+      AnimationTargetChanged();
+
+      // After unsetting href, we may still have xlink:href, so we
+      // should try to add it back.
+      const nsAttrValue* xlinkHref =
+        mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
+      if (xlinkHref) {
+        UpdateHrefTarget(this, xlinkHref->GetStringValue());
+      }
+    } else if (!HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
+      mHrefTarget.Unlink();
+      AnimationTargetChanged();
+    } // else: we unset xlink:href, but we still have href attribute, so keep
+      // mHrefTarget linking to href.
+  } else if (IsInUncomposedDoc() &&
+             !(aNamespaceID == kNameSpaceID_XLink &&
+               HasAttr(kNameSpaceID_None, nsGkAtoms::href))) {
+    // Note: "href" takes priority over xlink:href. So if "xlink:href" is being
+    // set here, we only let that update our target if "href" is *unset*.
     MOZ_ASSERT(aValue->Type() == nsAttrValue::eString,
                "Expected href attribute to be string type");
     UpdateHrefTarget(this, aValue->GetStringValue());
   } // else: we're not yet in a document -- we'll update the target on
     // next BindToTree call.
 
   return rv;
 }