Bug 1870822 - Simplify referrer usage in SVGObserverUtils r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D196836
This commit is contained in:
Robert Longson 2023-12-19 17:13:59 +00:00
parent 84705736a5
commit 1c30043b1e
2 changed files with 48 additions and 84 deletions

View File

@ -98,6 +98,40 @@ class URLAndReferrerInfoHashKey : public PLDHashEntryHdr {
RefPtr<const URLAndReferrerInfo> mKey;
};
/**
* 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* content,
nsIURI* aURI) {
MOZ_ASSERT(content);
// Content is in a shadow tree. If this URL was specified in the subtree
// referenced by the <use>, element, and that subtree came from a separate
// resource document, then we want the fragment-only URL to resolve to an
// element from the resource document. Otherwise, the URL was specified
// somewhere in the document with the <use> element, and we want the
// fragment-only URL to resolve to an element in that document.
if (SVGUseElement* use = content->GetContainingSVGUseShadowHost()) {
if (nsIURI* originalURI = use->GetSourceDocURI()) {
bool isEqualsExceptRef = false;
aURI->EqualsExceptRef(originalURI, &isEqualsExceptRef);
if (isEqualsExceptRef) {
return do_AddRef(originalURI);
}
}
}
// For a local-reference URL, resolve that fragment against the current
// document that relative URLs are resolved against.
return do_AddRef(content->OwnerDoc()->GetDocumentURI());
}
static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
nsIFrame* aFrame, const StyleComputedImageUrl& aURL) {
MOZ_ASSERT(aFrame);
@ -105,7 +139,7 @@ static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
nsCOMPtr<nsIURI> uri = aURL.GetURI();
if (aURL.IsLocalRef()) {
uri = SVGObserverUtils::GetBaseURLForLocalRef(aFrame->GetContent(), uri);
uri = GetBaseURLForLocalRef(aFrame->GetContent(), uri);
uri = aURL.ResolveLocalRef(uri);
}
@ -113,15 +147,12 @@ static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
return nullptr;
}
RefPtr<URLAndReferrerInfo> info =
new URLAndReferrerInfo(uri, aURL.ExtraData());
return info.forget();
return do_AddRef(new URLAndReferrerInfo(uri, aURL.ExtraData()));
}
static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
nsIContent* aContent, const nsAString& aURL,
nsIReferrerInfo* aReferrerInfo) {
// Like SVGObserverUtils::GetBaseURLForLocalRef, we want to resolve the
nsIContent* aContent, const nsAString& aURL) {
// Like GetBaseURLForLocalRef, we want to resolve the
// URL against any <use> element shadow tree's source document.
//
// Unlike GetBaseURLForLocalRef, we are assuming that the URL was specified
@ -148,15 +179,12 @@ static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
return nullptr;
}
RefPtr<URLAndReferrerInfo> info = new URLAndReferrerInfo(uri, aReferrerInfo);
return info.forget();
}
// There's no clear refererer policy spec about non-CSS SVG resource
// references Bug 1415044 to investigate which referrer we should use
nsIReferrerInfo* referrerInfo =
aContent->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources();
static already_AddRefed<URLAndReferrerInfo> ResolveURLUsingLocalRef(
nsIFrame* aFrame, const nsAString& aURL, nsIReferrerInfo* aReferrerInfo) {
MOZ_ASSERT(aFrame);
return ResolveURLUsingLocalRef(aFrame->GetContent(), aURL, aReferrerInfo);
return do_AddRef(new URLAndReferrerInfo(uri, referrerInfo));
}
class SVGFilterObserverList;
@ -1542,12 +1570,7 @@ SVGGeometryElement* SVGObserverUtils::GetAndObserveTextPathsPath(
return nullptr; // no URL
}
// There's no clear refererer policy spec about non-CSS SVG resource
// references Bug 1415044 to investigate which referrer we should use
nsIReferrerInfo* referrerInfo =
content->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources();
RefPtr<URLAndReferrerInfo> target =
ResolveURLUsingLocalRef(aTextPathFrame, href, referrerInfo);
RefPtr<URLAndReferrerInfo> target = ResolveURLUsingLocalRef(content, href);
property =
GetEffectProperty(target, aTextPathFrame, HrefAsTextPathProperty());
@ -1569,12 +1592,8 @@ SVGGeometryElement* SVGObserverUtils::GetAndObserveMPathsPath(
return nullptr; // no URL
}
nsIReferrerInfo* referrerInfo =
aSVGMPathElement->OwnerDoc()
->ReferrerInfoForInternalCSSAndSVGResources();
RefPtr<URLAndReferrerInfo> target =
ResolveURLUsingLocalRef(aSVGMPathElement, href, referrerInfo);
ResolveURLUsingLocalRef(aSVGMPathElement, href);
aSVGMPathElement->mMPathObserver =
new SVGMPathObserver(target, aSVGMPathElement);
@ -1622,28 +1641,10 @@ nsIFrame* SVGObserverUtils::GetAndObserveTemplate(
return nullptr; // no URL
}
// Convert href to an nsIURI
nsIContent* content = aFrame->GetContent();
RefPtr<URLAndReferrerInfo> info =
ResolveURLUsingLocalRef(aFrame->GetContent(), href);
nsCOMPtr<nsIURI> baseURI = content->GetBaseURI();
if (nsContentUtils::IsLocalRefURL(href)) {
baseURI = GetBaseURLForLocalRef(content, baseURI);
}
nsCOMPtr<nsIURI> targetURI;
nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(targetURI), href, content->GetUncomposedDoc(), baseURI);
if (!targetURI) {
return nullptr;
}
// There's no clear refererer policy spec about non-CSS SVG resource
// references. Bug 1415044 to investigate which referrer we should use.
nsIReferrerInfo* referrerInfo =
content->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources();
RefPtr<URLAndReferrerInfo> target =
new URLAndReferrerInfo(targetURI, referrerInfo);
observer = GetEffectProperty(target, aFrame, HrefToTemplateProperty());
observer = GetEffectProperty(info, aFrame, HrefToTemplateProperty());
}
return observer ? observer->GetAndObserveReferencedFrame() : nullptr;
@ -1868,29 +1869,4 @@ void SVGObserverUtils::InvalidateDirectRenderingObservers(
}
}
already_AddRefed<nsIURI> SVGObserverUtils::GetBaseURLForLocalRef(
nsIContent* content, nsIURI* aDocURI) {
MOZ_ASSERT(content);
// Content is in a shadow tree. If this URL was specified in the subtree
// referenced by the <use>, element, and that subtree came from a separate
// resource document, then we want the fragment-only URL to resolve to an
// element from the resource document. Otherwise, the URL was specified
// somewhere in the document with the <use> element, and we want the
// fragment-only URL to resolve to an element in that document.
if (SVGUseElement* use = content->GetContainingSVGUseShadowHost()) {
if (nsIURI* originalURI = use->GetSourceDocURI()) {
bool isEqualsExceptRef = false;
aDocURI->EqualsExceptRef(originalURI, &isEqualsExceptRef);
if (isEqualsExceptRef) {
return do_AddRef(originalURI);
}
}
}
// For a local-reference URL, resolve that fragment against the current
// document that relative URLs are resolved against.
return do_AddRef(content->OwnerDoc()->GetDocumentURI());
}
} // namespace mozilla

View File

@ -432,18 +432,6 @@ class SVGObserverUtils {
* invalidation changes for background-clip:text.
*/
static Element* GetAndObserveBackgroundClip(nsIFrame* aFrame);
/**
* 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);
};
} // namespace mozilla