Bug 1245751 - Part 5: Allow href without xlink on SVG <feImage> elements. draft
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 07 Jul 2016 14:22:57 +0800
changeset 407856 e77875a59e04cd29813178843c37267c13127704
parent 407855 15d69747c0376faf5ca947acaf34a762801da31e
child 407857 5c8ec9a1c90fbf88c4b95a0669ae1f07d3927810
push id28064
push userbmo:boris.chiou@gmail.com
push dateWed, 31 Aug 2016 04:26:14 +0000
bugs1245751
milestone51.0a1
Bug 1245751 - Part 5: Allow href without xlink on SVG <feImage> elements. MozReview-Commit-ID: 4h3mdwU4wwp
dom/svg/SVGFEImageElement.cpp
dom/svg/SVGFEImageElement.h
layout/svg/SVGFEImageFrame.cpp
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -26,19 +26,20 @@ namespace mozilla {
 namespace dom {
 
 JSObject*
 SVGFEImageElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return SVGFEImageElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
-nsSVGElement::StringInfo SVGFEImageElement::sStringInfo[2] =
+nsSVGElement::StringInfo SVGFEImageElement::sStringInfo[3] =
 {
   { &nsGkAtoms::result, kNameSpaceID_None, true },
+  { &nsGkAtoms::href, kNameSpaceID_None, true },
   { &nsGkAtoms::href, kNameSpaceID_XLink, true }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ISUPPORTS_INHERITED(SVGFEImageElement, SVGFEImageElementBase,
                             nsIDOMNode, nsIDOMElement, nsIDOMSVGElement,
@@ -64,17 +65,21 @@ SVGFEImageElement::~SVGFEImageElement()
 
 nsresult
 SVGFEImageElement::LoadSVGImage(bool aForce, bool aNotify)
 {
   // resolve href attribute
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
 
   nsAutoString href;
-  mStringAttributes[HREF].GetAnimValue(href, this);
+  if (mStringAttributes[HREF].IsExplicitlySet()) {
+    mStringAttributes[HREF].GetAnimValue(href, this);
+  } else {
+    mStringAttributes[XLINK_HREF].GetAnimValue(href, this);
+  }
   href.Trim(" \t\n\r");
 
   if (baseURI && !href.IsEmpty())
     NS_MakeAbsoluteURI(href, href, baseURI);
 
   // Make sure we don't get in a recursive death-spiral
   nsIDocument* doc = OwnerDoc();
   nsCOMPtr<nsIURI> hrefAsURI;
@@ -102,17 +107,19 @@ SVGFEImageElement::IsAttributeMapped(con
   return FindAttributeDependence(name, map) ||
     SVGFEImageElementBase::IsAttributeMapped(name);
 }
 
 nsresult
 SVGFEImageElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify)
 {
-  if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
+  if (aName == nsGkAtoms::href &&
+      (aNamespaceID == kNameSpaceID_XLink ||
+       aNamespaceID == kNameSpaceID_None)) {
 
     // If there isn't a frame we still need to load the image in case
     // the frame is created later e.g. by attaching to a document.
     // If there is a frame then it should deal with loading as the image
     // url may be animated.
     if (!GetPrimaryFrame()) {
       if (aValue) {
         LoadSVGImage(true, aNotify);
@@ -124,17 +131,18 @@ SVGFEImageElement::AfterSetAttr(int32_t 
 
   return SVGFEImageElementBase::AfterSetAttr(aNamespaceID, aName,
                                              aValue, aNotify);
 }
 
 void
 SVGFEImageElement::MaybeLoadSVGImage()
 {
-  if (mStringAttributes[HREF].IsExplicitlySet() &&
+  if ((mStringAttributes[HREF].IsExplicitlySet() ||
+       mStringAttributes[XLINK_HREF].IsExplicitlySet() ) &&
       (NS_FAILED(LoadSVGImage(false, true)) ||
        !LoadingEnabled())) {
     CancelImageRequests(true);
   }
 }
 
 nsresult
 SVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@@ -144,17 +152,18 @@ SVGFEImageElement::BindToTree(nsIDocumen
   nsresult rv = SVGFEImageElementBase::BindToTree(aDocument, aParent,
                                                   aBindingParent,
                                                   aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
                                     aCompileEventHandlers);
 
-  if (mStringAttributes[HREF].IsExplicitlySet()) {
+  if (mStringAttributes[HREF].IsExplicitlySet() ||
+      mStringAttributes[XLINK_HREF].IsExplicitlySet()) {
     // FIXME: Bug 660963 it would be nice if we could just have
     // ClearBrokenState update our state and do it fast...
     ClearBrokenState();
     RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
     nsContentUtils::AddScriptRunner(
       NewRunnableMethod(this, &SVGFEImageElement::MaybeLoadSVGImage));
   }
 
@@ -178,17 +187,19 @@ SVGFEImageElement::IntrinsicState() cons
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEImageElement)
 
 already_AddRefed<SVGAnimatedString>
 SVGFEImageElement::Href()
 {
-  return mStringAttributes[HREF].ToDOMAnimatedString(this);
+  return mStringAttributes[HREF].IsExplicitlySet()
+         ? mStringAttributes[HREF].ToDOMAnimatedString(this)
+         : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGFEImageElement methods
 
 FilterPrimitiveDescription
 SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                            const IntRect& aFilterSubregion,
--- a/dom/svg/SVGFEImageElement.h
+++ b/dom/svg/SVGFEImageElement.h
@@ -77,19 +77,19 @@ private:
   nsresult LoadSVGImage(bool aForce, bool aNotify);
 
 protected:
   virtual bool ProducesSRGB() override { return true; }
 
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
   virtual StringAttributesInfo GetStringInfo() override;
 
-  enum { RESULT, HREF };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
+  enum { RESULT, HREF, XLINK_HREF };
+  nsSVGString mStringAttributes[3];
+  static StringInfo sStringInfo[3];
 
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/layout/svg/SVGFEImageFrame.cpp
+++ b/layout/svg/SVGFEImageFrame.cpp
@@ -129,19 +129,24 @@ SVGFEImageFrame::AttributeChanged(int32_
                                   int32_t  aModType)
 {
   SVGFEImageElement *element = static_cast<SVGFEImageElement*>(mContent);
   if (element->AttributeAffectsRendering(aNameSpaceID, aAttribute)) {
     MOZ_ASSERT(GetParent()->GetType() == nsGkAtoms::svgFilterFrame,
                "Observers observe the filter, so that's what we must invalidate");
     nsSVGEffects::InvalidateDirectRenderingObservers(GetParent());
   }
-  if (aNameSpaceID == kNameSpaceID_XLink &&
+  if ((aNameSpaceID == kNameSpaceID_XLink ||
+       aNameSpaceID == kNameSpaceID_None) &&
       aAttribute == nsGkAtoms::href) {
-    if (element->mStringAttributes[SVGFEImageElement::HREF].IsExplicitlySet()) {
+    bool hrefIsSet =
+      element->mStringAttributes[SVGFEImageElement::HREF].IsExplicitlySet() ||
+      element->mStringAttributes[SVGFEImageElement::XLINK_HREF]
+        .IsExplicitlySet();
+    if (hrefIsSet) {
       element->LoadSVGImage(true, true);
     } else {
       element->CancelImageRequests(true);
     }
   }
 
   return nsFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
 }