Bug 1345377 - Implement URLValueData::HasRef. draft
authorcku <cku@mozilla.com>
Tue, 07 Mar 2017 17:31:48 +0800
changeset 495103 1369db1681233ae73b8edaa818e0d7dc085bfa7c
parent 494263 b7e42143bbbc9dc3e5c05bd1e93b6485ce1d0ad4
child 548281 e10fd6da84dc7e6b18a64f91b5b27eafa38dda46
push id48230
push userbmo:cku@mozilla.com
push dateWed, 08 Mar 2017 08:06:51 +0000
bugs1345377
milestone55.0a1
Bug 1345377 - Implement URLValueData::HasRef. Improve code readability. MozReview-Commit-ID: HDJ7TeyqCpN
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsStyleStruct.cpp
layout/svg/nsSVGEffects.cpp
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -2843,16 +2843,37 @@ css::URLValueData::GetURI() const
               nullptr, const_cast<nsIURI*>(mBaseURI.get()));
     mURI = new PtrHolder<nsIURI>(newURI.forget());
     mURIResolved = true;
   }
 
   return mURI;
 }
 
+bool
+css::URLValueData::HasRef() const
+{
+  if (IsLocalRef()) {
+    return true;
+  }
+
+  nsIURI* uri = GetURI();
+  if (!uri) {
+    return false;
+  }
+
+  nsAutoCString ref;
+  nsresult rv = uri->GetRef(ref);
+  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
+    return true;
+  }
+
+  return false;
+}
+
 already_AddRefed<nsIURI>
 css::URLValueData::ResolveLocalRef(nsIURI* aURI) const
 {
   nsCOMPtr<nsIURI> result = GetURI();
 
   if (result && mIsLocalRef) {
     nsCString ref;
     mURI->GetRef(ref);
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -133,16 +133,18 @@ public:
   // Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
   // pointers of the two URLValueData objects.
   bool DefinitelyEqualURIsAndPrincipal(const URLValueData& aOther) const;
 
   nsIURI* GetURI() const;
 
   bool IsLocalRef() const { return mIsLocalRef; }
 
+  bool HasRef() const;
+
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValueData)
 
   // When matching a url with mIsLocalRef set, resolve it against aURI;
   // Otherwise, ignore aURL and return mURL directly.
   already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aURI) const;
   already_AddRefed<nsIURI> ResolveLocalRef(nsIContent* aContent) const;
 
   // Serializes mURI as a computed URI value, taking into account mIsLocalRef
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2927,31 +2927,21 @@ nsStyleImageLayers::Layer::CalcDifferenc
     //   mask:url(#localMaskID); // The fragment of this URI is an ID of a mask
     //                           // element in local document.
     //   mask:url(b.svg#viewBoxID); // The fragment of this URI is an ID of a
     //                              // viewbox defined in b.svg.
     // That is, if mSourceURI has a fragment, it may link to a SVG mask; If
     // not, it "must" not link to a SVG mask.
     bool maybeSVGMask = false;
     if (mSourceURI) {
-      if (mSourceURI->IsLocalRef()) {
-        maybeSVGMask = true;
-      } else if (mSourceURI->GetURI()) {
-        mSourceURI->GetURI()->GetHasRef(&maybeSVGMask);
-      }
+      maybeSVGMask = mSourceURI->HasRef();
     }
 
-    if (!maybeSVGMask) {
-      if (aNewLayer.mSourceURI) {
-        if (aNewLayer.mSourceURI->IsLocalRef()) {
-          maybeSVGMask = true;
-        } else if (aNewLayer.mSourceURI->GetURI()) {
-          aNewLayer.mSourceURI->GetURI()->GetHasRef(&maybeSVGMask);
-        }
-      }
+    if (!maybeSVGMask && aNewLayer.mSourceURI) {
+      maybeSVGMask = aNewLayer.mSourceURI->HasRef();
     }
 
     // Return nsChangeHint_UpdateOverflow if either URI might link to an SVG
     // mask.
     if (maybeSVGMask) {
       // Mask changes require that we update the PreEffectsBBoxProperty,
       // which is done during overflow computation.
       hint |= nsChangeHint_UpdateOverflow;
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -1030,11 +1030,18 @@ nsSVGEffects::GetPaintURI(nsIFrame* aFra
 }
 
 already_AddRefed<nsIURI>
 nsSVGEffects::GetMaskURI(nsIFrame* aFrame, uint32_t aIndex)
 {
   const nsStyleSVGReset* svgReset = aFrame->StyleSVGReset();
   MOZ_ASSERT(svgReset->mMask.mLayers.Length() > aIndex);
 
-  return ResolveURLUsingLocalRef(aFrame,
-                                 svgReset->mMask.mLayers[aIndex].mSourceURI);
+  // mSourceURI can be used to address an SVG mask *only if* it contains a
+  // fragment.
+  const RefPtr<mozilla::css::URLValueData>& sourceURI =
+    svgReset->mMask.mLayers[aIndex].mSourceURI;
+  if (!sourceURI || !sourceURI->HasRef()) {
+    return nullptr;
+  }
+
+  return ResolveURLUsingLocalRef(aFrame, sourceURI);
 }