mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
Bug 1357432 (#750)
* Part 1. Move IsLocalRefURL to nsContentUtils to reuse this function. (port-rewrite)
`IsLocalRefURL` is originally designed to be used by URLValue only.
Since we need this function in SVGUseElement::LookupHref too, move it to nsContentUtils as a util function.
* Revert "Part 1. Move IsLocalRefURL to nsContentUtils to reuse this function. (port-rewrite)"
This reverts commit 19f010c62022e269f99066a8d90e3522fe31adaf.
* Part 1. Duplicate IsLocalRefURL to nsContentUtils to reuse this function.
`IsLocalRefURL` is originally designed to be used by URLValue only.
Since we need this function in SVGUseElement::LookupHref too, duplicate it to nsContentUtils as a util function.
This is a duplication because CSSValue uses stringbuffers and not nsStrings.
While Bug 1356060 - "Just use nsString in URLValueData" converts this use from stringbuffer to nsString, it builds on a bunch of vartype refactoring (nsString vs. nsAString, etc.) which is too much of a headache to deal with just to deduplicate this simple function.
* 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.
* Part 3. Resolve local-ref in SVGUseElement::LookupHref by nsSVGEffects::GetBaseURLForLocalRef.
* Part 4. Reftest for using local-ref as xlink:href value.
This commit is contained in:
parent
ad782894c8
commit
49fc92f4a1
7 changed files with 90 additions and 19 deletions
|
|
@ -9787,3 +9787,19 @@ nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel)
|
|||
|
||||
return reloadSucceeded;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsContentUtils::IsLocalRefURL(const nsString& aString)
|
||||
{
|
||||
// Find the first non-"C0 controls + space" character.
|
||||
const char16_t* current = aString.get();
|
||||
for (; *current != '\0'; current++) {
|
||||
if (*current > 0x20) {
|
||||
// if the first non-"C0 controls + space" character is '#', this is a
|
||||
// local-ref URL.
|
||||
return *current == '#';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2730,6 +2730,13 @@ public:
|
|||
|
||||
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
|
||||
|
||||
/**
|
||||
* Detect whether a string is a (CSS) local-url.
|
||||
* https://drafts.csswg.org/css-values/#local-urls
|
||||
*/
|
||||
static bool
|
||||
IsLocalRefURL(const nsString& aString);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsSVGEffects.h"
|
||||
|
||||
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Use)
|
||||
|
||||
|
|
@ -418,11 +419,15 @@ SVGUseElement::LookupHref()
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> originURI =
|
||||
mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
|
||||
nsCOMPtr<nsIURI> baseURI = nsContentUtils::IsLocalRefURL(href)
|
||||
? nsSVGEffects::GetBaseURLForLocalRef(this, originURI)
|
||||
: originURI;
|
||||
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsCOMPtr<nsIURI> baseURI = mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
|
||||
GetComposedDoc(), baseURI);
|
||||
|
||||
mSource.Reset(this, targetURI);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ fuzzy-if(skiaContent,1,300) == tspan-xy-05.svg tspan-xy-ref.svg # bug 773482
|
|||
fuzzy-if(skiaContent,1,300) == tspan-xy-06.svg tspan-xy-ref.svg # bug 773482
|
||||
fuzzy-if(skiaContent,1,100) == tspan-xy-anchor-middle-01.svg tspan-xy-anchor-middle-ref.svg # bug 773482
|
||||
fuzzy-if(skiaContent,1,100) == tspan-xy-anchor-end-01.svg tspan-xy-anchor-end-ref.svg # bug 773482
|
||||
== use-localRef-link.html pass.svg
|
||||
== userSpaceOnUse-and-pattern-01.svg userSpaceOnUse-and-pattern-01-ref.svg
|
||||
== viewBox-and-pattern-01.svg pass.svg
|
||||
== viewBox-and-pattern-02.svg pass.svg
|
||||
|
|
|
|||
16
layout/reftests/svg/use-localRef-link.html
Normal file
16
layout/reftests/svg/use-localRef-link.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<base href="/test">
|
||||
</head>
|
||||
<body style="background-color: lime;">
|
||||
<svg width="100" height="100">
|
||||
<defs>
|
||||
<rect id="a" x="0" y="0" width="50" height="50" fill="lime"/>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="50" height="50" fill="red"/>
|
||||
<use xlink:href="#a"/>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
|
@ -888,24 +888,13 @@ nsSVGEffects::InvalidateDirectRenderingObservers(nsIFrame* aFrame, uint32_t aFla
|
|||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
|
@ -933,12 +922,37 @@ ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -626,11 +626,23 @@ public:
|
|||
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_*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue