Bug 1357432 - Part 2. Implement nsSVGEffects::GetBaseURLForLocalRef to export local-ref-url-resolving logic. draft
authorcku <cku@mozilla.com>
Thu, 20 Apr 2017 15:58:19 +0800
changeset 565683 86f3241de747f1e936ccf51288eb3ef661c58de8
parent 565676 6ddd25df8da07327aa847a08d19791bd71eb4323
child 565684 b9c52e209b62ad5331c9f8f858f7f865bec88f4e
push id54957
push userbmo:cku@mozilla.com
push dateThu, 20 Apr 2017 07:59:21 +0000
bugs1357432
milestone55.0a1
Bug 1357432 - Part 2. Implement nsSVGEffects::GetBaseURLForLocalRef to export local-ref-url-resolving logic. ResolveURLUsingLocalRef is designed to be internally used by nsSVGEffects::Get-{SVGEffect}-URI functions. Since we also need it in SVGUseElement::LookupHref, make it public in nsSVGEffects. MozReview-Commit-ID: Hsvs8Uzahrz
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -905,34 +905,23 @@ void
 nsSVGEffects::InvalidateDirectRenderingObservers(nsIFrame* aFrame, uint32_t aFlags /* = 0 */)
 {
   nsIContent* content = aFrame->GetContent();
   if (content && content->IsElement()) {
     InvalidateDirectRenderingObservers(content->AsElement(), aFlags);
   }
 }
 
-static already_AddRefed<nsIURI>
-ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
+already_AddRefed<nsIURI>
+nsSVGEffects::GetBaseURLForLocalRef(nsIContent* content, nsIURI* aDocURI)
 {
-  MOZ_ASSERT(aFrame);
-
-  if (!aURL) {
-    return nullptr;
-  }
-
-  // Non-local-reference URL.
-  if (!aURL->IsLocalRef()) {
-    nsCOMPtr<nsIURI> result = aURL->GetURI();
-    return result.forget();
-  }
+  MOZ_ASSERT(content);
 
   // For a local-reference URL, resolve that fragment against the current
   // document that relative URLs are resolved against.
-  nsIContent* content = aFrame->GetContent();
   nsCOMPtr<nsIURI> baseURI = content->OwnerDoc()->GetDocumentURI();
 
   if (content->IsInAnonymousSubtree()) {
     nsIContent* bindingParent = content->GetBindingParent();
     nsCOMPtr<nsIURI> originalURI;
 
     // content is in a shadow tree.  If this URL was specified in the subtree
     // referenced by the <use>(or -moz-binding) element, and that subtree came
@@ -950,22 +939,47 @@ ResolveURLUsingLocalRef(nsIFrame* aFrame
           originalURI = binding->GetSourceDocURI();
         } else {
           MOZ_ASSERT(content->IsInNativeAnonymousSubtree(),
                      "an non-native anonymous tree which is not from "
                      "an XBL binding?");
         }
       }
 
-      if (originalURI && aURL->EqualsExceptRef(originalURI)) {
-        baseURI = originalURI;
+      if (originalURI) {
+        bool isEqualsExceptRef = false;
+        aDocURI->EqualsExceptRef(originalURI, &isEqualsExceptRef);
+        if (isEqualsExceptRef) {
+          baseURI = originalURI;
+        }
       }
     }
   }
 
+  return baseURI.forget();
+}
+
+static already_AddRefed<nsIURI>
+ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
+{
+  MOZ_ASSERT(aFrame);
+
+  if (!aURL) {
+    return nullptr;
+  }
+
+  // Non-local-reference URL.
+  if (!aURL->IsLocalRef()) {
+    nsCOMPtr<nsIURI> result = aURL->GetURI();
+    return result.forget();
+  }
+
+  nsCOMPtr<nsIURI> baseURI =
+    nsSVGEffects::GetBaseURLForLocalRef(aFrame->GetContent(), aURL->GetURI());
+
   return aURL->ResolveLocalRef(baseURI);
 }
 
 already_AddRefed<nsIURI>
 nsSVGEffects::GetMarkerURI(nsIFrame* aFrame,
                            RefPtr<css::URLValue> nsStyleSVG::* aMarker)
 {
   return ResolveURLUsingLocalRef(aFrame, aFrame->StyleSVG()->*aMarker);
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -661,16 +661,28 @@ public:
   GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter);
 
   /**
    * A helper function to resolve paint-server URL.
    */
   static already_AddRefed<nsIURI>
   GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint);
 
-    /**
+  /**
    * A helper function to resolve SVG mask URL.
    */
   static already_AddRefed<nsIURI>
   GetMaskURI(nsIFrame* aFrame, uint32_t aIndex);
+
+  /**
+   * Return a baseURL for resolving a local-ref URL.
+   *
+   * @param aContent an element which uses a local-ref property. Here are some
+   *                 examples:
+   *                   <rect fill=url(#foo)>
+   *                   <circle clip-path=url(#foo)>
+   *                   <use xlink:href="#foo">
+   */
+  static already_AddRefed<nsIURI>
+  GetBaseURLForLocalRef(nsIContent* aContent, nsIURI* aDocURI);
 };
 
 #endif /*NSSVGEFFECTS_H_*/