Bug 652991 - Part 9. Using FragmentOrURL to represent PanitServer url.
MozReview-Commit-ID: IZf0fGantoB
--- 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));