Bug 1245751 - Part 2: Allow href without xlink on SVG <use> elements.
MozReview-Commit-ID: 28op2ZoRm6X
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -33,18 +33,19 @@ SVGUseElement::WrapNode(JSContext *aCx,
nsSVGElement::LengthInfo SVGUseElement::sLengthInfo[4] =
{
{ &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
{ &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
{ &nsGkAtoms::width, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
{ &nsGkAtoms::height, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
};
-nsSVGElement::StringInfo SVGUseElement::sStringInfo[1] =
+nsSVGElement::StringInfo SVGUseElement::sStringInfo[2] =
{
+ { &nsGkAtoms::href, kNameSpaceID_None, true },
{ &nsGkAtoms::href, kNameSpaceID_XLink, true }
};
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_CYCLE_COLLECTION_CLASS(SVGUseElement)
@@ -104,17 +105,19 @@ SVGUseElement::Clone(mozilla::dom::NodeI
}
return NS_FAILED(rv1) ? rv1 : rv2;
}
already_AddRefed<SVGAnimatedString>
SVGUseElement::Href()
{
- return mStringAttributes[HREF].ToDOMAnimatedString(this);
+ return mStringAttributes[HREF].IsExplicitlySet()
+ ? mStringAttributes[HREF].ToDOMAnimatedString(this)
+ : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
}
//----------------------------------------------------------------------
already_AddRefed<SVGAnimatedLength>
SVGUseElement::X()
{
return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this);
@@ -390,19 +393,25 @@ SVGUseElement::SyncWidthOrHeight(nsIAtom
return;
}
}
void
SVGUseElement::LookupHref()
{
nsAutoString href;
- mStringAttributes[HREF].GetAnimValue(href, this);
- if (href.IsEmpty())
+ if (mStringAttributes[HREF].IsExplicitlySet()) {
+ mStringAttributes[HREF].GetAnimValue(href, this);
+ } else {
+ mStringAttributes[XLINK_HREF].GetAnimValue(href, this);
+ }
+
+ if (href.IsEmpty()) {
return;
+ }
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIURI> baseURI = mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
GetComposedDoc(), baseURI);
mSource.Reset(this, targetURI);
}
--- a/dom/svg/SVGUseElement.h
+++ b/dom/svg/SVGUseElement.h
@@ -105,19 +105,19 @@ protected:
void LookupHref();
void TriggerReclone();
void UnlinkSource();
enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
nsSVGLength2 mLengthAttributes[4];
static LengthInfo sLengthInfo[4];
- enum { HREF };
- nsSVGString mStringAttributes[1];
- static StringInfo sStringInfo[1];
+ enum { HREF, XLINK_HREF };
+ nsSVGString mStringAttributes[2];
+ static StringInfo sStringInfo[2];
nsCOMPtr<nsIContent> mOriginal; // if we've been cloned, our "real" copy
nsCOMPtr<nsIContent> mClone; // cloned tree
SourceReference mSource; // observed element
};
} // namespace dom
} // namespace mozilla
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -112,18 +112,17 @@ nsSVGUseFrame::Init(nsIContent* aC
nsresult
nsSVGUseFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
SVGUseElement *useElement = static_cast<SVGUseElement*>(mContent);
if (aNameSpaceID == kNameSpaceID_None) {
- if (aAttribute == nsGkAtoms::x ||
- aAttribute == nsGkAtoms::y) {
+ if (aAttribute == nsGkAtoms::x || aAttribute == nsGkAtoms::y) {
// make sure our cached transform matrix gets (lazily) updated
mCanvasTM = nullptr;
nsLayoutUtils::PostRestyleEvent(
useElement, nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else if (aAttribute == nsGkAtoms::width ||
@@ -139,18 +138,21 @@ nsSVGUseFrame::AttributeChanged(int32_t
}
if (invalidate) {
nsLayoutUtils::PostRestyleEvent(
useElement, nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
}
}
- } else if (aNameSpaceID == kNameSpaceID_XLink &&
- aAttribute == nsGkAtoms::href) {
+ }
+
+ if ((aNameSpaceID == kNameSpaceID_XLink ||
+ aNameSpaceID == kNameSpaceID_None) &&
+ aAttribute == nsGkAtoms::href) {
// we're changing our nature, clear out the clone information
nsLayoutUtils::PostRestyleEvent(
useElement, nsRestyleHint(0),
nsChangeHint_InvalidateRenderingObservers);
nsSVGUtils::ScheduleReflowSVG(this);
useElement->mOriginal = nullptr;
useElement->UnlinkSource();
useElement->TriggerReclone();