Bug 652991 - Part 9. Using FragmentOrURL to represent PanitServer url. draft
authorcku <cku@mozilla.com>
Tue, 05 Jul 2016 01:00:15 +0800
changeset 395504 6246bc5610b005049caed3e32d0c85fd8bc5ee78
parent 395503 2a71088216b10645906f5b3cf7b3ed1735a45689
child 395505 07fb15aef522c4d6c76e0342685369ddd8b27cfd
push id24801
push usercku@mozilla.com
push dateTue, 02 Aug 2016 14:45:11 +0000
bugs652991
milestone51.0a1
Bug 652991 - Part 9. Using FragmentOrURL to represent PanitServer url. MozReview-Commit-ID: IZf0fGantoB
layout/style/StyleAnimationValue.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
layout/svg/nsSVGUtils.cpp
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -280,16 +280,29 @@ AppendCSSShadowValue(const nsCSSShadowIt
   }
 
   nsCSSValueList *resultItem = new nsCSSValueList;
   resultItem->mValue.SetArrayValue(arr, eCSSUnit_Array);
   *aResultTail = resultItem;
   aResultTail = &resultItem->mNext;
 }
 
+static already_AddRefed<mozilla::css::URLValue>
+FragmentOrURLToURLValue(FragmentOrURL* aUrl, nsIDocument* aDoc)
+{
+  nsString path;
+  aUrl->GetSourceString(path);
+  RefPtr<nsStringBuffer> uriStringBuffer = nsCSSValue::BufferFromString(path);
+  RefPtr<mozilla::css::URLValue> result =
+    new mozilla::css::URLValue(aUrl->GetSourceURL(), uriStringBuffer,
+                               aDoc->GetDocumentURI(), aDoc->NodePrincipal());
+
+  return result.forget();
+}
+
 // Like nsStyleCoord::CalcValue, but with length in float pixels instead
 // of nscoord.
 struct PixelCalcValue
 {
   float mLength, mPercent;
   bool mHasPercent;
 };
 
@@ -3940,26 +3953,19 @@ StyleAnimationValue::ExtractComputedValu
         case eCSSProperty_clip_path: {
           const nsStyleSVGReset* svgReset =
             static_cast<const nsStyleSVGReset*>(styleStruct);
           const nsStyleClipPath& clipPath = svgReset->mClipPath;
           const StyleClipPathType type = clipPath.GetType();
 
           if (type == StyleClipPathType::URL) {
             nsIDocument* doc = aStyleContext->PresContext()->Document();
-            nsString pathString;
-            clipPath.GetURL()->GetSourceString(pathString);
-            RefPtr<nsStringBuffer> uriAsStringBuffer =
-              nsCSSValue::BufferFromString(pathString);
-
             RefPtr<mozilla::css::URLValue> url =
-              new mozilla::css::URLValue(clipPath.GetURL()->GetSourceURL(),
-                                         uriAsStringBuffer,
-                                         doc->GetDocumentURI(),
-                                         doc->NodePrincipal());
+              FragmentOrURLToURLValue(clipPath.GetURL(), doc);
+
             auto result = MakeUnique<nsCSSValue>();
             result->SetURLValue(url);
             aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
           } else if (type == StyleClipPathType::Box) {
             aComputedValue.SetIntValue(clipPath.GetSizingBox(),
                                        eUnit_Enumerated);
           } else if (type == StyleClipPathType::Shape) {
             RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
@@ -3984,25 +3990,19 @@ StyleAnimationValue::ExtractComputedValu
           for (uint32_t i = 0; i < filters.Length(); ++i) {
             nsCSSValueList *item = new nsCSSValueList;
             *resultTail = item;
             resultTail = &item->mNext;
             const nsStyleFilter& filter = filters[i];
             int32_t type = filter.GetType();
             if (type == NS_STYLE_FILTER_URL) {
               nsIDocument* doc = aStyleContext->PresContext()->Document();
-              nsString pathString;
-              filter.GetURL()->GetSourceString(pathString);
-              RefPtr<nsStringBuffer> uriAsStringBuffer =
-                nsCSSValue::BufferFromString(pathString);
               RefPtr<mozilla::css::URLValue> url =
-                new mozilla::css::URLValue(filter.GetURL()->GetSourceURL(),
-                                           uriAsStringBuffer,
-                                           doc->GetDocumentURI(),
-                                           doc->NodePrincipal());
+                FragmentOrURLToURLValue(filter.GetURL(), doc);
+
               item->mValue.SetURLValue(url);
             } else {
               nsCSSKeyword functionName =
                 nsCSSProps::ValueToKeywordEnum(type,
                   nsCSSProps::kFilterFunctionKTable);
               nsCSSValue::Array* filterArray =
                 item->mValue.InitFunction(functionName, 1);
               if (type >= NS_STYLE_FILTER_BLUR && type <= NS_STYLE_FILTER_HUE_ROTATE) {
@@ -4161,25 +4161,21 @@ StyleAnimationValue::ExtractComputedValu
         return true;
       }
       if (paint.mType == eStyleSVGPaintType_Server) {
         if (!paint.mPaint.mPaintServer) {
           NS_WARNING("Null paint server");
           return false;
         }
         nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
-        RefPtr<nsStringBuffer> uriAsStringBuffer =
-          GetURIAsUtf16StringBuffer(paint.mPaint.mPaintServer);
-        NS_ENSURE_TRUE(!!uriAsStringBuffer, false);
+
         nsIDocument* doc = aStyleContext->PresContext()->Document();
         RefPtr<mozilla::css::URLValue> url =
-          new mozilla::css::URLValue(paint.mPaint.mPaintServer,
-                                     uriAsStringBuffer,
-                                     doc->GetDocumentURI(),
-                                     doc->NodePrincipal());
+          FragmentOrURLToURLValue(paint.mPaint.mPaintServer, doc);
+
         pair->mXValue.SetURLValue(url);
         pair->mYValue.SetColorValue(paint.mFallbackColor);
         aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
                                                     eUnit_CSSValuePair);
         return true;
       }
       if (paint.mType == eStyleSVGPaintType_ContextFill ||
           paint.mType == eStyleSVGPaintType_ContextStroke) {
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5557,20 +5557,22 @@ nsComputedDOMStyle::GetSVGPaintFor(bool 
     }
     case eStyleSVGPaintType_Color:
     {
       SetToRGBAColor(val, paint->mPaint.mColor);
       break;
     }
     case eStyleSVGPaintType_Server:
     {
+      // Bug 1288812 - we should only serialize fragment for local-ref URL.
       RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
       RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
-
-      val->SetURI(paint->mPaint.mPaintServer);
+      nsCOMPtr<nsIURI> paintServerURI =
+        paint->mPaint.mPaintServer->GetSourceURL();
+      val->SetURI(paintServerURI);
       SetToRGBAColor(fallback, paint->mFallbackColor);
 
       valueList->AppendCSSValue(val.forget());
       valueList->AppendCSSValue(fallback.forget());
       return valueList.forget();
     }
     case eStyleSVGPaintType_ContextFill:
     {
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9244,18 +9244,18 @@ SetSVGPaint(const nsCSSValue& aValue, co
                       color, aConditions)) {
     aResult.SetType(eStyleSVGPaintType_Color);
     aResult.mPaint.mColor = color;
   } else if (aValue.GetUnit() == eCSSUnit_Pair) {
     const nsCSSValuePair& pair = aValue.GetPairValue();
 
     if (pair.mXValue.GetUnit() == eCSSUnit_URL) {
       aResult.SetType(eStyleSVGPaintType_Server);
-      aResult.mPaint.mPaintServer = pair.mXValue.GetURLValue();
-      NS_IF_ADDREF(aResult.mPaint.mPaintServer);
+      aResult.mPaint.mPaintServer = new FragmentOrURL();
+      aResult.mPaint.mPaintServer->SetValue(&pair.mXValue);
     } else if (pair.mXValue.GetUnit() == eCSSUnit_Enumerated) {
 
       switch (pair.mXValue.GetIntValue()) {
       case NS_COLOR_CONTEXT_FILL:
         aResult.SetType(eStyleSVGPaintType_ContextFill);
         break;
       case NS_COLOR_CONTEXT_STROKE:
         aResult.SetType(eStyleSVGPaintType_ContextStroke);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1456,18 +1456,17 @@ nsStyleSVGPaint::nsStyleSVGPaint(nsStyle
 nsStyleSVGPaint::nsStyleSVGPaint(const nsStyleSVGPaint& aSource)
   : mType(nsStyleSVGPaintType(0))
   , mFallbackColor(NS_RGB(0, 0, 0))
 {
   SetType(aSource.mType);
 
   mFallbackColor = aSource.mFallbackColor;
   if (mType == eStyleSVGPaintType_Server) {
-    mPaint.mPaintServer = aSource.mPaint.mPaintServer;
-    NS_IF_ADDREF(mPaint.mPaintServer);
+    mPaint.mPaintServer = new FragmentOrURL(*aSource.mPaint.mPaintServer);
   } else {
     mPaint.mColor = aSource.mPaint.mColor;
   }
 }
 
 nsStyleSVGPaint::~nsStyleSVGPaint()
 {
   Reset();
@@ -1478,17 +1477,17 @@ nsStyleSVGPaint::Reset()
 {
   SetType(nsStyleSVGPaintType(0));
 }
 
 void
 nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType)
 {
   if (mType == eStyleSVGPaintType_Server) {
-    NS_IF_RELEASE(mPaint.mPaintServer);
+    delete mPaint.mPaintServer;
     mPaint.mPaintServer = nullptr;
   } else {
     mPaint.mColor = NS_RGB(0, 0, 0);
   }
   mType = aType;
 }
 
 nsStyleSVGPaint&
@@ -1497,18 +1496,17 @@ nsStyleSVGPaint::operator=(const nsStyle
   if (this == &aOther) {
     return *this;
   }
 
   SetType(aOther.mType);
 
   mFallbackColor = aOther.mFallbackColor;
   if (mType == eStyleSVGPaintType_Server) {
-    mPaint.mPaintServer = aOther.mPaint.mPaintServer;
-    NS_IF_ADDREF(mPaint.mPaintServer);
+    mPaint.mPaintServer = new FragmentOrURL(*aOther.mPaint.mPaintServer);
   } else {
     mPaint.mColor = aOther.mPaint.mColor;
   }
   return *this;
 }
 
 bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3255,17 +3255,17 @@ enum nsStyleSVGOpacitySource : uint8_t {
   eStyleSVGOpacitySource_ContextFillOpacity,
   eStyleSVGOpacitySource_ContextStrokeOpacity
 };
 
 struct nsStyleSVGPaint
 {
   union {
     nscolor mColor;
-    nsIURI *mPaintServer;
+    FragmentOrURL* mPaintServer;
   } mPaint;
   nsStyleSVGPaintType mType;
   nscolor mFallbackColor;
 
   explicit nsStyleSVGPaint(nsStyleSVGPaintType aType = nsStyleSVGPaintType(0));
   nsStyleSVGPaint(const nsStyleSVGPaint& aSource);
   ~nsStyleSVGPaint();
   void Reset();
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -590,36 +590,40 @@ nsSVGEffects::GetEffectProperties(nsIFra
   MOZ_ASSERT(style->mMask.mImageCount > 0);
   result.mMask = style->mMask.HasLayerWithImage()
                  ? GetOrCreateMaskProperty(aFrame) : nullptr;
 
   return result;
 }
 
 nsSVGPaintServerFrame *
-nsSVGEffects::GetPaintServer(nsIFrame *aTargetFrame, const nsStyleSVGPaint *aPaint,
+nsSVGEffects::GetPaintServer(nsIFrame *aTargetFrame,
+                             nsStyleSVGPaint nsStyleSVG::* aPaint,
                              PaintingPropertyDescriptor aType)
 {
-  if (aPaint->mType != eStyleSVGPaintType_Server)
+  const nsStyleSVG* svgStyle = aTargetFrame->StyleSVG();
+  if ((svgStyle->*aPaint).mType != eStyleSVGPaintType_Server)
     return nullptr;
 
   // If we're looking at a frame within SVG text, then we need to look up
   // to find the right frame to get the painting property off.  We should at
   // least look up past a text frame, and if the text frame's parent is the
   // anonymous block frame, then we look up to its parent (the SVGTextFrame).
   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> paintServerURL = nsSVGEffects::GetPaintURI(frame, aPaint);
   nsSVGPaintingProperty *property =
-    nsSVGEffects::GetPaintingProperty(aPaint->mPaint.mPaintServer, frame, aType);
+    nsSVGEffects::GetPaintingProperty(paintServerURL, frame, aType);
   if (!property)
     return nullptr;
   nsIFrame *result = property->GetReferencedFrame();
   if (!result)
     return nullptr;
 
   nsIAtom *type = result->GetType();
   if (type != nsGkAtoms::svgLinearGradientFrame &&
@@ -942,8 +946,19 @@ nsSVGEffects::GetFilterURI(nsIFrame* aFr
 already_AddRefed<nsIURI>
 nsSVGEffects::GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter)
 {
   MOZ_ASSERT(aFrame->StyleEffects()->mFilters.Length());
   MOZ_ASSERT(aFilter.GetType() == NS_STYLE_FILTER_URL);
 
   return ResolveFragmentOrURL(aFrame, aFilter.GetURL());
 }
+
+already_AddRefed<nsIURI>
+nsSVGEffects::GetPaintURI(nsIFrame* aFrame,
+                          nsStyleSVGPaint nsStyleSVG::* aPaint)
+{
+  const nsStyleSVG* svgStyle = aFrame->StyleSVG();
+  MOZ_ASSERT((svgStyle->*aPaint).mType ==
+             nsStyleSVGPaintType::eStyleSVGPaintType_Server);
+
+  return ResolveFragmentOrURL(aFrame, (svgStyle->*aPaint).mPaint.mPaintServer);
+}
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -460,17 +460,17 @@ public:
                                        nsSVGPaintingProperty)
   NS_DECLARE_FRAME_PROPERTY_DELETABLE(BackgroundImageProperty,
                                       URIObserverHashtable)
 
   /**
    * Get the paint server for a aTargetFrame.
    */
   static nsSVGPaintServerFrame *GetPaintServer(nsIFrame *aTargetFrame,
-                                               const nsStyleSVGPaint *aPaint,
+                                               nsStyleSVGPaint nsStyleSVG::* aPaint,
                                                PaintingPropertyDescriptor aProperty);
 
   struct EffectProperties {
     nsSVGFilterProperty*   mFilter;
     nsSVGMaskProperty*     mMask;
     nsSVGPaintingProperty* mClipPath;
 
     /**
@@ -613,11 +613,17 @@ public:
   static already_AddRefed<nsIURI>
   GetFilterURI(nsIFrame* aFrame, uint32_t aIndex);
 
   /**
    * A helper function to resolve filter URL.
    */
   static already_AddRefed<nsIURI>
   GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter);
+
+  /**
+   * A helper function to resolve paint-server URL.
+   */
+  static already_AddRefed<nsIURI>
+  GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint);
 };
 
 #endif /*NSSVGEFFECTS_H_*/
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1317,17 +1317,17 @@ SetupInheritablePaint(const DrawTarget* 
                       float& aOpacity,
                       gfxTextContextPaint* aOuterContextPaint,
                       SVGTextContextPaint::Paint& aTargetPaint,
                       nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                       nsSVGEffects::PaintingPropertyDescriptor aProperty)
 {
   const nsStyleSVG *style = aFrame->StyleSVG();
   nsSVGPaintServerFrame *ps =
-    nsSVGEffects::GetPaintServer(aFrame, &(style->*aFillOrStroke), aProperty);
+    nsSVGEffects::GetPaintServer(aFrame, aFillOrStroke, aProperty);
 
   if (ps) {
     RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
                                 aFillOrStroke, aOpacity);
     if (pattern) {
       aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
       return;
@@ -1428,17 +1428,17 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame*
     // Combine the group opacity into the fill opacity (we will have skipped
     // creating an offscreen surface to apply the group opacity).
     fillOpacity *= opacity;
   }
 
   const DrawTarget* dt = aContext->GetDrawTarget();
 
   nsSVGPaintServerFrame *ps =
-    nsSVGEffects::GetPaintServer(aFrame, &style->mFill,
+    nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mFill,
                                  nsSVGEffects::FillProperty());
   if (ps) {
     RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
                                 &nsStyleSVG::mFill, fillOpacity);
     if (pattern) {
       pattern->CacheColorStops(dt);
       aOutPattern->Init(*pattern->GetPattern(dt));
@@ -1496,17 +1496,17 @@ nsSVGUtils::MakeStrokePatternFor(nsIFram
     // Combine the group opacity into the stroke opacity (we will have skipped
     // creating an offscreen surface to apply the group opacity).
     strokeOpacity *= opacity;
   }
 
   const DrawTarget* dt = aContext->GetDrawTarget();
 
   nsSVGPaintServerFrame *ps =
-    nsSVGEffects::GetPaintServer(aFrame, &style->mStroke,
+    nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mStroke,
                                  nsSVGEffects::StrokeProperty());
   if (ps) {
     RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
                                 &nsStyleSVG::mStroke, strokeOpacity);
     if (pattern) {
       pattern->CacheColorStops(dt);
       aOutPattern->Init(*pattern->GetPattern(dt));