diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index abc3d1d6e301..871af7966af0 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2143,10 +2143,11 @@ nsComputedDOMStyle::DoGetImageLayerImage(const nsStyleImageLayers& aLayers) // Instead, we store the local URI in one place -- on Layer::mSourceURI. // Hence, we must serialize using mSourceURI (instead of // SetValueToStyleImage()/mImage) in this case. - if (aLayers.mLayers[i].mSourceURI.IsLocalRef()) { + if (aLayers.mLayers[i].mSourceURI && + aLayers.mLayers[i].mSourceURI->IsLocalRef()) { // This is how we represent a 'mask-image' reference for a local URI, // such as 'mask-image:url(#mymask)' or 'mask:url(#mymask)' - SetValueToFragmentOrURL(&aLayers.mLayers[i].mSourceURI, val); + SetValueToURLValue(aLayers.mLayers[i].mSourceURI, val); } else { SetValueToStyleImage(image, val); } @@ -6168,11 +6169,7 @@ nsComputedDOMStyle::DoGetMask() RefPtr val = new nsROCSSPrimitiveValue; - if (firstLayer.mSourceURI.GetSourceURL()) { - SetValueToFragmentOrURL(&firstLayer.mSourceURI, val); - } else { - val->SetIdent(eCSSKeyword_none); - } + SetValueToURLValue(firstLayer.mSourceURI, val); return val.forget(); } diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 28897384b73a..da444f22e998 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -6704,6 +6704,30 @@ struct BackgroundItemComputer } }; +template <> +struct BackgroundItemComputer> +{ + static void ComputeValue(nsStyleContext* aStyleContext, + const nsCSSValueList* aSpecifiedValue, + RefPtr& aComputedValue, + RuleNodeCacheConditions& aConditions) + { + switch (aSpecifiedValue->mValue.GetUnit()) { + case eCSSUnit_Null: + break; + case eCSSUnit_URL: + aComputedValue = aSpecifiedValue->mValue.GetURLStructValue(); + break; + case eCSSUnit_Image: + aComputedValue = aSpecifiedValue->mValue.GetImageStructValue(); + break; + default: + aComputedValue = nullptr; + break; + } + } +}; + /* Helper function for ComputePositionValue. * This function computes a single PositionCoord from two nsCSSValue objects, * which represent an edge and an offset from that edge. @@ -9938,7 +9962,8 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct, svgReset->mMask.mLayers, parentSVGReset->mMask.mLayers, &nsStyleImageLayers::Layer::mSourceURI, - FragmentOrURL(), parentSVGReset->mMask.mImageCount, + RefPtr(), + parentSVGReset->mMask.mImageCount, svgReset->mMask.mImageCount, maxItemCount, rebuild, conditions); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index e0017b025fce..614bfc3b8b6c 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -60,14 +60,16 @@ EqualURIs(nsIURI *aURI1, nsIURI *aURI2) } static bool -DefinitelyEqualURIs(css::URLValue* aURI1, css::URLValue* aURI2) +DefinitelyEqualURIs(css::URLValueData* aURI1, + css::URLValueData* aURI2) { return aURI1 == aURI2 || (aURI1 && aURI2 && aURI1->DefinitelyEqualURIs(*aURI2)); } static bool -DefinitelyEqualURIsAndPrincipal(css::URLValue* aURI1, css::URLValue* aURI2) +DefinitelyEqualURIsAndPrincipal(css::URLValueData* aURI1, + css::URLValueData* aURI2) { return aURI1 == aURI2 || (aURI1 && aURI2 && aURI1->DefinitelyEqualURIsAndPrincipal(*aURI2)); @@ -2545,7 +2547,8 @@ nsStyleImageLayers::HasLayerWithImage() const // mLayers[i].mImage can be empty if mask-image prop value is a reference // to SVG mask element. // So we need to test both mSourceURI and mImage. - if (mLayers[i].mSourceURI.GetSourceURL() || !mLayers[i].mImage.IsEmpty()) { + if ((mLayers[i].mSourceURI && mLayers[i].mSourceURI->GetURI()) || + !mLayers[i].mImage.IsEmpty()) { return true; } } @@ -2779,7 +2782,7 @@ nsStyleImageLayers::Layer::operator==(const Layer& aOther) const mImage == aOther.mImage && mMaskMode == aOther.mMaskMode && mComposite == aOther.mComposite && - mSourceURI == aOther.mSourceURI; + DefinitelyEqualURIs(mSourceURI, aOther.mSourceURI); } nsChangeHint @@ -2787,7 +2790,7 @@ nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewL nsChangeHint aPositionChangeHint) const { nsChangeHint hint = nsChangeHint(0); - if (mSourceURI != aNewLayer.mSourceURI) { + if (!DefinitelyEqualURIs(mSourceURI, aNewLayer.mSourceURI)) { hint |= nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects; // If Layer::mSourceURI links to a SVG mask, it has a fragment. Not vice @@ -2802,17 +2805,21 @@ nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewL // 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.IsLocalRef()) { - maybeSVGMask = true; - } else if (mSourceURI.GetSourceURL()) { - mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask); + if (mSourceURI) { + if (mSourceURI->IsLocalRef()) { + maybeSVGMask = true; + } else if (mSourceURI->GetURI()) { + mSourceURI->GetURI()->GetHasRef(&maybeSVGMask); + } } if (!maybeSVGMask) { - if (aNewLayer.mSourceURI.IsLocalRef()) { - maybeSVGMask = true; - } else if (aNewLayer.mSourceURI.GetSourceURL()) { - aNewLayer.mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask); + if (aNewLayer.mSourceURI) { + if (aNewLayer.mSourceURI->IsLocalRef()) { + maybeSVGMask = true; + } else if (aNewLayer.mSourceURI->GetURI()) { + aNewLayer.mSourceURI->GetURI()->GetHasRef(&maybeSVGMask); + } } } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 52eb0ada0562..787726986e4e 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -705,13 +705,14 @@ struct nsStyleImageLayers { friend struct Layer; struct Layer { nsStyleImage mImage; // [reset] - mozilla::FragmentOrURL mSourceURI; // [reset] + RefPtr mSourceURI; // [reset] // mask-only property // This property is used for mask layer only. // For a background layer, it should always // be the initial value, which is nullptr. // Store mask-image URI so that we can resolve - // SVG mask path later. + // SVG mask path later. (Might be a URLValue + // or an ImageValue.) mozilla::Position mPosition; // [reset] Size mSize; // [reset] uint8_t mClip; // [reset] See nsStyleConsts.h diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp index a570f46dcce8..98ba37f7b2dc 100644 --- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -943,7 +943,7 @@ ResolveFragmentOrURL(nsIFrame* aFrame, const FragmentOrURL* aFragmentOrURL) } static already_AddRefed -ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValue* aURL) +ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL) { MOZ_ASSERT(aFrame); @@ -1050,6 +1050,6 @@ nsSVGEffects::GetMaskURI(nsIFrame* aFrame, uint32_t aIndex) const nsStyleSVGReset* svgReset = aFrame->StyleSVGReset(); MOZ_ASSERT(svgReset->mMask.mLayers.Length() > aIndex); - return ResolveFragmentOrURL(aFrame, - &svgReset->mMask.mLayers[aIndex].mSourceURI); + return ResolveURLUsingLocalRef(aFrame, + svgReset->mMask.mLayers[aIndex].mSourceURI); }