--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -48,16 +48,41 @@ nsSVGRenderingObserver::StopListening()
static nsSVGRenderingObserverList *
GetObserverList(Element *aElement)
{
return static_cast<nsSVGRenderingObserverList*>
(aElement->GetProperty(nsGkAtoms::renderingobserverlist));
}
+static already_AddRefed<nsIURI>
+ResolveLocalReferencedURL(nsIURI* aURI, nsIContent* aElement)
+{
+ nsCOMPtr<nsIURI> result;
+
+ if (!aURI) {
+ return result.forget();
+ }
+
+ bool isLocalRef = false;
+ aURI->GetIsLocalRef(&isLocalRef);
+ if (isLocalRef) {
+ nsCOMPtr<nsIURI> baseURI= aElement->GetBaseURI();
+ baseURI->Clone(getter_AddRefs(result));
+
+ nsAutoCString ref;
+ aURI->GetRef(ref);
+ result->SetRef(ref);
+ } else {
+ result = aURI;
+ }
+
+ return result.forget();
+}
+
Element*
nsSVGRenderingObserver::GetReferencedElement()
{
Element* target = GetTarget();
#ifdef DEBUG
if (target) {
nsSVGRenderingObserverList *observerList = GetObserverList(target);
bool inObserverList = observerList && observerList->Contains(this);
@@ -550,28 +575,35 @@ nsSVGEffects::EffectProperties
nsSVGEffects::GetEffectProperties(nsIFrame *aFrame)
{
NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
EffectProperties result;
const nsStyleSVGReset *style = aFrame->StyleSVGReset();
result.mFilter = GetOrCreateFilterProperty(aFrame);
if (style->mClipPath.GetType() == NS_STYLE_CLIP_PATH_URL) {
+ nsCOMPtr<nsIURI> effectURL =
+ ResolveLocalReferencedURL(style->mClipPath.GetURL(), aFrame->GetContent());
+
result.mClipPath =
- GetPaintingProperty(style->mClipPath.GetURL(), aFrame, ClipPathProperty());
+ GetPaintingProperty(effectURL, aFrame, ClipPathProperty());
} else {
result.mClipPath = nullptr;
}
// FIXME: Bug 1228280.
// Before fixing bug 1228280, we support only single svg mask as before.
MOZ_ASSERT(style->mMask.mImageCount > 0);
- nsCOMPtr<nsIURI> uri = style->mMask.mLayers[0].mSourceURI;
- result.mMask = uri ? GetPaintingProperty(uri, aFrame, MaskProperty()) :
- nullptr;
+ nsCOMPtr<nsIURI> effectURL =
+ ResolveLocalReferencedURL(style->mMask.mLayers[0].mSourceURI,
+ aFrame->GetContent());
+
+ result.mMask = effectURL
+ ? GetPaintingProperty(effectURL, aFrame, MaskProperty())
+ : nullptr;
return result;
}
nsSVGPaintServerFrame *
nsSVGEffects::GetPaintServer(nsIFrame *aTargetFrame, const nsStyleSVGPaint *aPaint,
ObserverPropertyDescriptor aType)
{
@@ -585,18 +617,23 @@ nsSVGEffects::GetPaintServer(nsIFrame *a
nsIFrame* frame = aTargetFrame;
if (frame->GetContent()->IsNodeOfType(nsINode::eTEXT)) {
frame = frame->GetParent();
nsIFrame* grandparent = frame->GetParent();
if (grandparent && grandparent->GetType() == nsGkAtoms::svgTextFrame) {
frame = grandparent;
}
}
+
+ nsCOMPtr<nsIURI> effectURL =
+ ResolveLocalReferencedURL(aPaint->mPaint.mPaintServer,
+ aTargetFrame->GetContent());
+
nsSVGPaintingProperty *property =
- nsSVGEffects::GetPaintingProperty(aPaint->mPaint.mPaintServer, frame, aType);
+ nsSVGEffects::GetPaintingProperty(effectURL, frame, aType);
if (!property)
return nullptr;
nsIFrame *result = property->GetReferencedFrame();
if (!result)
return nullptr;
nsIAtom *type = result->GetType();
if (type != nsGkAtoms::svgLinearGradientFrame &&
@@ -649,21 +686,25 @@ nsSVGEffects::UpdateEffects(nsIFrame *aF
// Ensure that the filter is repainted correctly
// We can't do that in DoUpdate as the referenced frame may not be valid
GetOrCreateFilterProperty(aFrame);
if (aFrame->GetType() == nsGkAtoms::svgPathGeometryFrame &&
static_cast<nsSVGPathGeometryElement*>(aFrame->GetContent())->IsMarkable()) {
// Set marker properties here to avoid reference loops
const nsStyleSVG *style = aFrame->StyleSVG();
- GetEffectProperty(style->mMarkerStart, aFrame, MarkerBeginProperty(),
+ nsCOMPtr<nsIURI> effectURL;
+ effectURL = ResolveLocalReferencedURL(style->mMarkerStart, aFrame->GetContent());
+ GetEffectProperty(effectURL, aFrame, MarkerBeginProperty(),
CreateMarkerProperty);
- GetEffectProperty(style->mMarkerMid, aFrame, MarkerMiddleProperty(),
+ effectURL = ResolveLocalReferencedURL(style->mMarkerMid, aFrame->GetContent());
+ GetEffectProperty(effectURL, aFrame, MarkerMiddleProperty(),
CreateMarkerProperty);
- GetEffectProperty(style->mMarkerEnd, aFrame, MarkerEndProperty(),
+ effectURL = ResolveLocalReferencedURL(style->mMarkerEnd, aFrame->GetContent());
+ GetEffectProperty(effectURL, aFrame, MarkerEndProperty(),
CreateMarkerProperty);
}
}
nsSVGFilterProperty *
nsSVGEffects::GetFilterProperty(nsIFrame *aFrame)
{
NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");