Bug 1245499 - Do not trigger a download request for CSS "mask-image" when it's set to a local-reference URI draft
authorcku@mozilla.com <cku@mozilla.com>
Thu, 26 May 2016 13:49:54 +0800
changeset 371190 b0d80a5c8fec6609768a804f5f48e068aaf4f8a8
parent 371122 8d0aadfe7da782d415363880008b4ca027686137
child 521947 99701c0e0336fae3b71c8caf6fcfc1b86f978210
push id19277
push usercku@mozilla.com
push dateThu, 26 May 2016 05:59:39 +0000
bugs1245499
milestone49.0a1
Bug 1245499 - Do not trigger a download request for CSS "mask-image" when it's set to a local-reference URI MozReview-Commit-ID: DPtvKQ2UQof
layout/style/nsCSSDataBlock.cpp
layout/style/nsRuleNode.cpp
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -55,16 +55,33 @@ ShouldIgnoreColors(nsRuleData *aRuleData
 static void
 TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
                            nsStyleContext* aContext, nsCSSProperty aProperty,
                            bool aForTokenStream)
 {
   MOZ_ASSERT(aDocument);
 
   if (aValue.GetUnit() == eCSSUnit_URL) {
+#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
+    // The 'mask-image' property accepts local reference URIs.
+    // For example,
+    //   mask-image: url(#mask_id); // refer to a SVG mask element, whose id is
+    //                              // "mask_id", in the current document.
+    // For such 'mask-image' values (pointing to an in-document element),
+    // there is no need to trigger image download.
+    if (aProperty == eCSSProperty_mask_image) {
+      nsIURI* docURI = aDocument->GetDocumentURI();
+      nsIURI* imageURI = aValue.GetURLValue();
+      bool isEqualExceptRef = false;
+      nsresult  rv = imageURI->EqualsExceptRef(docURI, &isEqualExceptRef);
+      if (NS_SUCCEEDED(rv) && isEqualExceptRef) {
+        return;
+      }
+    }
+#endif
     aValue.StartImageLoad(aDocument);
     if (aForTokenStream && aContext) {
       CSSVariableImageTable::Add(aContext, aProperty,
                                  aValue.GetImageStructValue());
     }
   }
   else if (aValue.GetUnit() == eCSSUnit_Image) {
     // If we already have a request, see if this document needs to clone it.
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1254,23 +1254,35 @@ static void SetStyleImage(nsStyleContext
     }
     case eCSSUnit_Element:
       aResult.SetElementId(aValue.GetStringBufferValue());
       break;
     case eCSSUnit_Initial:
     case eCSSUnit_Unset:
     case eCSSUnit_None:
       break;
+    case eCSSUnit_URL:
+    {
+#ifdef DEBUG
+      nsIDocument* currentDoc = aStyleContext->PresContext()->Document();
+      nsIURI* docURI = currentDoc->GetDocumentURI();
+      nsIURI* imageURI = aValue.GetURLValue();
+      bool isEqualExceptRef = false;
+      imageURI->EqualsExceptRef(docURI, &isEqualExceptRef);
+      // Either we have eCSSUnit_URL values for if-visited style contexts,
+      // which we can safely treat like 'none', or aValue refers to an
+      // in-document resource. Otherwise this is an unexpected unit.
+      NS_ASSERTION(aStyleContext->IsStyleIfVisited() || isEqualExceptRef,
+                   "unexpected unit; maybe nsCSSValue::Image::Image() failed?");
+#endif
+
+      break;
+    }
     default:
-      // We might have eCSSUnit_URL values for if-visited style
-      // contexts, which we can safely treat like 'none'.  Otherwise
-      // this is an unexpected unit.
-      NS_ASSERTION(aStyleContext->IsStyleIfVisited() &&
-                   aValue.GetUnit() == eCSSUnit_URL,
-                   "unexpected unit; maybe nsCSSValue::Image::Image() failed?");
+      MOZ_ASSERT_UNREACHABLE("Unexpected Unit type.");
       break;
   }
 }
 
 // flags for SetDiscrete - align values with SETCOORD_* constants
 // where possible
 
 #define SETDSC_NORMAL                 0x01   // N
@@ -6570,17 +6582,18 @@ struct BackgroundItemComputer<nsCSSValue
 template <>
 struct BackgroundItemComputer<nsCSSValueList, nsCOMPtr<nsIURI> >
 {
   static void ComputeValue(nsStyleContext* aStyleContext,
                            const nsCSSValueList* aSpecifiedValue,
                            nsCOMPtr<nsIURI>& aComputedValue,
                            RuleNodeCacheConditions& aConditions)
   {
-    if (eCSSUnit_Image == aSpecifiedValue->mValue.GetUnit()) {
+    if (eCSSUnit_Image == aSpecifiedValue->mValue.GetUnit() ||
+        eCSSUnit_URL == aSpecifiedValue->mValue.GetUnit()) {
       aComputedValue = aSpecifiedValue->mValue.GetURLValue();
     } else if (eCSSUnit_Null != aSpecifiedValue->mValue.GetUnit()) {
       aComputedValue = nullptr;
     }
   }
 };
 
 /* Helper function for ComputePositionValue.