Bug 1245751 - Part 11: Allow href without xlink on SVG Animation elements.
MozReview-Commit-ID: LJnJgHipDMP
--- 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;
}