Bug 652991 - Part 4. using FragmentURL in SVG clippath and filter.
MozReview-Commit-ID: JJMNAwyYgBN
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -3951,20 +3951,21 @@ StyleAnimationValue::ExtractComputedValu
case eCSSProperty_clip_path: {
const nsStyleSVGReset* svgReset =
static_cast<const nsStyleSVGReset*>(styleStruct);
const nsStyleClipPath& clipPath = svgReset->mClipPath;
const int32_t type = clipPath.GetType();
if (type == NS_STYLE_CLIP_PATH_URL) {
nsIDocument* doc = aStyleContext->PresContext()->Document();
+ nsCOMPtr<nsIURI> pathURI = clipPath.GetURL(doc);
RefPtr<nsStringBuffer> uriAsStringBuffer =
- GetURIAsUtf16StringBuffer(clipPath.GetURL());
+ GetURIAsUtf16StringBuffer(pathURI);
RefPtr<mozilla::css::URLValue> url =
- new mozilla::css::URLValue(clipPath.GetURL(),
+ new mozilla::css::URLValue(pathURI,
uriAsStringBuffer,
doc->GetDocumentURI(),
doc->NodePrincipal());
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(url);
aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
} else if (type == NS_STYLE_CLIP_PATH_BOX) {
aComputedValue.SetIntValue(clipPath.GetSizingBox(), eUnit_Enumerated);
@@ -3991,20 +3992,21 @@ 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();
+ nsCOMPtr<nsIURI> filterURI = filter.GetURL(doc);
RefPtr<nsStringBuffer> uriAsStringBuffer =
- GetURIAsUtf16StringBuffer(filter.GetURL());
+ GetURIAsUtf16StringBuffer(filterURI);
RefPtr<mozilla::css::URLValue> url =
- new mozilla::css::URLValue(filter.GetURL(),
+ new mozilla::css::URLValue(filterURI,
uriAsStringBuffer,
doc->GetDocumentURI(),
doc->NodePrincipal());
item->mValue.SetURLValue(url);
} else {
nsCSSKeyword functionName =
nsCSSProps::ValueToKeywordEnum(type,
nsCSSProps::kFilterFunctionKTable);
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -6002,18 +6002,21 @@ nsComputedDOMStyle::DoGetClipPath()
switch (svg->mClipPath.GetType()) {
case NS_STYLE_CLIP_PATH_SHAPE:
return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(),
svg->mClipPath.GetSizingBox());
case NS_STYLE_CLIP_PATH_BOX:
return CreatePrimitiveValueForClipPath(nullptr,
svg->mClipPath.GetSizingBox());
case NS_STYLE_CLIP_PATH_URL: {
+ nsIDocument* doc = mStyleContext->PresContext()->Document();
+ nsCOMPtr<nsIURI> pathURI = svg->mClipPath.GetURL(doc);
+
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
- val->SetURI(svg->mClipPath.GetURL());
+ val->SetURI(pathURI);
return val.forget();
}
case NS_STYLE_CLIP_PATH_NONE: {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(eCSSKeyword_none);
return val.forget();
}
default:
@@ -6034,17 +6037,19 @@ nsComputedDOMStyle::SetCssTextToCoord(ns
already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter(
const nsStyleFilter& aStyleFilter)
{
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
// Handle url().
if (aStyleFilter.GetType() == NS_STYLE_FILTER_URL) {
- value->SetURI(aStyleFilter.GetURL());
+ nsIDocument* doc = mStyleContext->PresContext()->Document();
+ nsCOMPtr<nsIURI> filterURI = aStyleFilter.GetURL(doc);
+ value->SetURI(filterURI);
return value.forget();
}
// Filter function name and opening parenthesis.
nsAutoString filterFunctionString;
AppendASCIItoUTF16(
nsCSSProps::ValueToKeyword(aStyleFilter.GetType(),
nsCSSProps::kFilterFunctionKTable),
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9733,21 +9733,17 @@ bool
nsRuleNode::SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
const nsCSSValue& aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
nsCSSUnit unit = aValue.GetUnit();
if (unit == eCSSUnit_URL) {
- nsIURI* url = aValue.GetURLValue();
- if (!url)
- return false;
- aStyleFilter->SetURL(url);
- return true;
+ return aStyleFilter->SetURL(&aValue);
}
MOZ_ASSERT(unit == eCSSUnit_Function, "expected a filter function");
nsCSSValue::Array* filterFunction = aValue.GetArrayValue();
nsCSSKeyword functionName =
(nsCSSKeyword)filterFunction->Item(0).GetIntValue();
@@ -9842,20 +9838,17 @@ nsRuleNode::ComputeSVGResetData(void* aS
svgReset->mClipPath = nsStyleClipPath();
break;
case eCSSUnit_Inherit:
conditions.SetUncacheable();
svgReset->mClipPath = parentSVGReset->mClipPath;
break;
case eCSSUnit_URL: {
svgReset->mClipPath = nsStyleClipPath();
- nsIURI* url = clipPathValue->GetURLValue();
- if (url) {
- svgReset->mClipPath.SetURL(url);
- }
+ svgReset->mClipPath.SetURL(clipPathValue);
break;
}
case eCSSUnit_Array: {
svgReset->mClipPath = nsStyleClipPath();
SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
mPresContext, conditions);
break;
}
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1086,28 +1086,27 @@ FragmentURL::ReleaseRef()
}
}
// --------------------
// nsStyleClipPath
//
nsStyleClipPath::nsStyleClipPath()
: mType(NS_STYLE_CLIP_PATH_NONE)
- , mURL(nullptr)
, mSizingBox(NS_STYLE_CLIP_SHAPE_SIZING_NOBOX)
{
}
nsStyleClipPath::nsStyleClipPath(const nsStyleClipPath& aSource)
: mType(NS_STYLE_CLIP_PATH_NONE)
- , mURL(nullptr)
, mSizingBox(NS_STYLE_CLIP_SHAPE_SIZING_NOBOX)
{
if (aSource.mType == NS_STYLE_CLIP_PATH_URL) {
- SetURL(aSource.mURL);
+ mURL = aSource.mURL;
+ mType = NS_STYLE_CLIP_PATH_URL;
} else if (aSource.mType == NS_STYLE_CLIP_PATH_SHAPE) {
SetBasicShape(aSource.mBasicShape, aSource.mSizingBox);
} else if (aSource.mType == NS_STYLE_CLIP_PATH_BOX) {
SetSizingBox(aSource.mSizingBox);
}
}
nsStyleClipPath::~nsStyleClipPath()
@@ -1118,17 +1117,18 @@ nsStyleClipPath::~nsStyleClipPath()
nsStyleClipPath&
nsStyleClipPath::operator=(const nsStyleClipPath& aOther)
{
if (this == &aOther) {
return *this;
}
if (aOther.mType == NS_STYLE_CLIP_PATH_URL) {
- SetURL(aOther.mURL);
+ mURL = aOther.mURL;
+ mType = NS_STYLE_CLIP_PATH_URL;
} else if (aOther.mType == NS_STYLE_CLIP_PATH_SHAPE) {
SetBasicShape(aOther.mBasicShape, aOther.mSizingBox);
} else if (aOther.mType == NS_STYLE_CLIP_PATH_BOX) {
SetSizingBox(aOther.mSizingBox);
} else {
ReleaseRef();
mSizingBox = NS_STYLE_CLIP_SHAPE_SIZING_NOBOX;
mType = NS_STYLE_CLIP_PATH_NONE;
@@ -1139,50 +1139,51 @@ nsStyleClipPath::operator=(const nsStyle
bool
nsStyleClipPath::operator==(const nsStyleClipPath& aOther) const
{
if (mType != aOther.mType) {
return false;
}
if (mType == NS_STYLE_CLIP_PATH_URL) {
- return EqualURIs(mURL, aOther.mURL);
+ return aOther.mURL == mURL;
} else if (mType == NS_STYLE_CLIP_PATH_SHAPE) {
return *mBasicShape == *aOther.mBasicShape &&
mSizingBox == aOther.mSizingBox;
} else if (mType == NS_STYLE_CLIP_PATH_BOX) {
return mSizingBox == aOther.mSizingBox;
}
return true;
}
void
nsStyleClipPath::ReleaseRef()
{
if (mType == NS_STYLE_CLIP_PATH_SHAPE) {
NS_ASSERTION(mBasicShape, "expected pointer");
mBasicShape->Release();
+ mBasicShape = nullptr;
} else if (mType == NS_STYLE_CLIP_PATH_URL) {
- NS_ASSERTION(mURL, "expected pointer");
- mURL->Release();
+ mURL.ReleaseRef();
}
- // mBasicShap, mURL, etc. are all pointers in a union of pointers. Nulling
- // one of them nulls all of them:
- mURL = nullptr;
}
-void
-nsStyleClipPath::SetURL(nsIURI* aURL)
+bool
+nsStyleClipPath::SetURL(const nsCSSValue* aValue)
{
- NS_ASSERTION(aURL, "expected pointer");
+ if (!aValue->GetURLValue()) {
+ return false;
+ }
+
ReleaseRef();
- mURL = aURL;
- mURL->AddRef();
+
+ mURL.SetURL(aValue);
mType = NS_STYLE_CLIP_PATH_URL;
+ return true;
}
void
nsStyleClipPath::SetBasicShape(nsStyleBasicShape* aBasicShape, uint8_t aSizingBox)
{
NS_ASSERTION(aBasicShape, "expected pointer");
ReleaseRef();
mBasicShape = aBasicShape;
@@ -1210,17 +1211,17 @@ nsStyleFilter::nsStyleFilter()
}
nsStyleFilter::nsStyleFilter(const nsStyleFilter& aSource)
: mType(NS_STYLE_FILTER_NONE)
, mDropShadow(nullptr)
{
MOZ_COUNT_CTOR(nsStyleFilter);
if (aSource.mType == NS_STYLE_FILTER_URL) {
- SetURL(aSource.mURL);
+ mURL = aSource.mURL;
} else if (aSource.mType == NS_STYLE_FILTER_DROP_SHADOW) {
SetDropShadow(aSource.mDropShadow);
} else if (aSource.mType != NS_STYLE_FILTER_NONE) {
SetFilterParameter(aSource.mFilterParameter, aSource.mType);
}
}
nsStyleFilter::~nsStyleFilter()
@@ -1231,17 +1232,17 @@ nsStyleFilter::~nsStyleFilter()
nsStyleFilter&
nsStyleFilter::operator=(const nsStyleFilter& aOther)
{
if (this == &aOther)
return *this;
if (aOther.mType == NS_STYLE_FILTER_URL) {
- SetURL(aOther.mURL);
+ mURL = aOther.mURL;
} else if (aOther.mType == NS_STYLE_FILTER_DROP_SHADOW) {
SetDropShadow(aOther.mDropShadow);
} else if (aOther.mType != NS_STYLE_FILTER_NONE) {
SetFilterParameter(aOther.mFilterParameter, aOther.mType);
} else {
ReleaseRef();
mType = NS_STYLE_FILTER_NONE;
}
@@ -1252,56 +1253,59 @@ nsStyleFilter::operator=(const nsStyleFi
bool
nsStyleFilter::operator==(const nsStyleFilter& aOther) const
{
if (mType != aOther.mType) {
return false;
}
if (mType == NS_STYLE_FILTER_URL) {
- return EqualURIs(mURL, aOther.mURL);
+ return aOther.mURL == mURL;
} else if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
return *mDropShadow == *aOther.mDropShadow;
} else if (mType != NS_STYLE_FILTER_NONE) {
return mFilterParameter == aOther.mFilterParameter;
}
return true;
}
void
nsStyleFilter::ReleaseRef()
{
if (mType == NS_STYLE_FILTER_DROP_SHADOW) {
NS_ASSERTION(mDropShadow, "expected pointer");
mDropShadow->Release();
+ mDropShadow = nullptr;
} else if (mType == NS_STYLE_FILTER_URL) {
- NS_ASSERTION(mURL, "expected pointer");
- mURL->Release();
+ mURL.ReleaseRef();
}
- mURL = nullptr;
}
void
nsStyleFilter::SetFilterParameter(const nsStyleCoord& aFilterParameter,
int32_t aType)
{
ReleaseRef();
mFilterParameter = aFilterParameter;
mType = aType;
}
-void
-nsStyleFilter::SetURL(nsIURI* aURL)
+bool
+nsStyleFilter::SetURL(const nsCSSValue* aValue)
{
- NS_ASSERTION(aURL, "expected pointer");
+ if (!aValue->GetURLValue()) {
+ return false;
+ }
+
ReleaseRef();
- mURL = aURL;
- mURL->AddRef();
+
+ mURL.SetURL(aValue);
mType = NS_STYLE_FILTER_URL;
+ return true;
}
void
nsStyleFilter::SetDropShadow(nsCSSShadowArray* aDropShadow)
{
NS_ASSERTION(aDropShadow, "expected pointer");
ReleaseRef();
mDropShadow = aDropShadow;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3502,41 +3502,40 @@ struct nsStyleClipPath
bool operator!=(const nsStyleClipPath& aOther) const {
return !(*this == aOther);
}
int32_t GetType() const {
return mType;
}
- nsIURI* GetURL() const {
+ already_AddRefed<nsIURI> GetURL(nsIDocument* aCurrentDoc) const {
NS_ASSERTION(mType == NS_STYLE_CLIP_PATH_URL, "wrong clip-path type");
- return mURL;
- }
- void SetURL(nsIURI* aURL);
+ return mURL.Resolve(aCurrentDoc);
+ }
+ bool SetURL(const nsCSSValue* aValue);
nsStyleBasicShape* GetBasicShape() const {
NS_ASSERTION(mType == NS_STYLE_CLIP_PATH_SHAPE, "wrong clip-path type");
return mBasicShape;
}
void SetBasicShape(nsStyleBasicShape* mBasicShape,
uint8_t aSizingBox = NS_STYLE_CLIP_SHAPE_SIZING_NOBOX);
uint8_t GetSizingBox() const { return mSizingBox; }
void SetSizingBox(uint8_t aSizingBox);
private:
void ReleaseRef();
void* operator new(size_t) = delete;
-
int32_t mType; // see NS_STYLE_CLIP_PATH_* constants in nsStyleConsts.h
union {
nsStyleBasicShape* mBasicShape;
- nsIURI* mURL;
+ FragmentURL mURL;
};
uint8_t mSizingBox; // see NS_STYLE_CLIP_SHAPE_SIZING_* constants in nsStyleConsts.h
};
struct nsStyleFilter
{
nsStyleFilter();
nsStyleFilter(const nsStyleFilter& aSource);
@@ -3557,35 +3556,35 @@ struct nsStyleFilter
NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
mType != NS_STYLE_FILTER_URL &&
mType != NS_STYLE_FILTER_NONE, "wrong filter type");
return mFilterParameter;
}
void SetFilterParameter(const nsStyleCoord& aFilterParameter,
int32_t aType);
- nsIURI* GetURL() const {
+ already_AddRefed<nsIURI> GetURL(nsIDocument* aCurrentDoc) const {
NS_ASSERTION(mType == NS_STYLE_FILTER_URL, "wrong filter type");
- return mURL;
- }
- void SetURL(nsIURI* aURL);
+ return mURL.Resolve(aCurrentDoc);
+ }
+ bool SetURL(const nsCSSValue* aValue);
nsCSSShadowArray* GetDropShadow() const {
NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
return mDropShadow;
}
void SetDropShadow(nsCSSShadowArray* aDropShadow);
private:
void ReleaseRef();
int32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
nsStyleCoord mFilterParameter; // coord, percent, factor, angle
union {
- nsIURI* mURL;
+ FragmentURL mURL;
nsCSSShadowArray* mDropShadow;
};
};
template<>
struct nsTArray_CopyChooser<nsStyleFilter>
{
typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -273,19 +273,19 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(nsSVGFilterChainObserver, mReferences)
nsSVGFilterChainObserver::nsSVGFilterChainObserver(const nsTArray<nsStyleFilter>& aFilters,
nsIContent* aFilteredElement)
{
for (uint32_t i = 0; i < aFilters.Length(); i++) {
if (aFilters[i].GetType() != NS_STYLE_FILTER_URL)
continue;
-
+ nsCOMPtr<nsIURI> filterURL = aFilters[i].GetURL(aFilteredElement->OwnerDoc());
RefPtr<nsSVGFilterReference> reference =
- new nsSVGFilterReference(aFilters[i].GetURL(), aFilteredElement, this);
+ new nsSVGFilterReference(filterURL, aFilteredElement, this);
mReferences.AppendElement(reference);
}
}
nsSVGFilterChainObserver::~nsSVGFilterChainObserver()
{
for (uint32_t i = 0; i < mReferences.Length(); i++) {
mReferences[i]->DetachFromChainObserver();
@@ -576,18 +576,21 @@ nsSVGEffects::GetEffectProperties(nsIFra
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) {
+ nsIDocument* doc = aFrame->StyleContext()->PresContext()->Document();
+ nsCOMPtr<nsIURI> pathURI = style->mClipPath.GetURL(doc);
+
result.mClipPath =
- GetPaintingProperty(style->mClipPath.GetURL(), aFrame, ClipPathProperty());
+ GetPaintingProperty(pathURI, aFrame, ClipPathProperty());
} else {
result.mClipPath = nullptr;
}
MOZ_ASSERT(style->mMask.mImageCount > 0);
result.mMask = style->mMask.HasLayerWithImage()
? GetOrCreateMaskProperty(aFrame) : nullptr;
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsSVGFilterInstance.cpp
@@ -115,25 +115,25 @@ nsSVGFilterInstance::ComputeBounds()
nsSVGFilterFrame*
nsSVGFilterInstance::GetFilterFrame()
{
if (mFilter.GetType() != NS_STYLE_FILTER_URL) {
// The filter is not an SVG reference filter.
return nullptr;
}
- nsIURI* url = mFilter.GetURL();
- if (!url) {
- NS_NOTREACHED("an nsStyleFilter of type URL should have a non-null URL");
+ // Get the target element to use as a point of reference for looking up the
+ // filter element.
+ if (!mTargetContent) {
return nullptr;
}
- // Get the target element to use as a point of reference for looking up the
- // filter element.
- if (!mTargetContent) {
+ nsCOMPtr<nsIURI> url = mFilter.GetURL(mTargetContent->OwnerDoc());
+ if (!url) {
+ NS_NOTREACHED("an nsStyleFilter of type URL should have a non-null URL");
return nullptr;
}
// Look up the filter element by URL.
nsReferencedElement filterElement;
bool watch = false;
filterElement.Reset(mTargetContent, url, watch);
Element* element = filterElement.get();