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
--- 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_*/