Bug 652991 - Part 2. Create FragmentOrURL to hold both local-ref/non-local-ref URL.
MozReview-Commit-ID: FVPNqxk3Uyr
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -61,16 +61,23 @@ EqualURIs(nsIURI *aURI1, nsIURI *aURI2)
static bool
EqualURIs(mozilla::css::URLValue *aURI1, mozilla::css::URLValue *aURI2)
{
return aURI1 == aURI2 || // handle null==null, and optimize
(aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
}
+static
+bool EqualURIs(const FragmentOrURL* aURI1, const FragmentOrURL* aURI2)
+{
+ return aURI1 == aURI2 || // handle null==null, and optimize
+ (aURI1 && aURI2 && *aURI1 == *aURI2);
+}
+
static bool
EqualImages(imgIRequest *aImage1, imgIRequest* aImage2)
{
if (aImage1 == aImage2) {
return true;
}
if (!aImage1 || !aImage2) {
@@ -999,16 +1006,113 @@ nsStyleBasicShape::GetShapeTypeName() co
case nsStyleBasicShape::Type::eInset:
return eCSSKeyword_inset;
}
NS_NOTREACHED("unexpected type");
return eCSSKeyword_UNKNOWN;
}
// --------------------
+// FragmentOrURL
+//
+
+void
+FragmentOrURL::SetValue(const nsCSSValue* aValue)
+{
+ mozilla::css::URLValue *urlVal = aValue->GetURLStructValue();
+ MOZ_ASSERT_IF(urlVal->GetLocalURLFlag(), urlVal->GetURI());
+ mIsLocalRef = urlVal->GetLocalURLFlag();
+
+ mURL = urlVal->GetURI();
+
+#ifdef DEBUG
+ if (mIsLocalRef) {
+ bool hasRef = false;
+ mURL->GetHasRef(&hasRef);
+ MOZ_ASSERT(hasRef);
+ }
+#endif
+}
+
+void
+FragmentOrURL::SetNull()
+{
+ mURL = nullptr;
+ mIsLocalRef = false;
+}
+
+FragmentOrURL&
+FragmentOrURL::operator=(const FragmentOrURL& aOther)
+{
+ mIsLocalRef = aOther.mIsLocalRef;
+ mURL = aOther.mURL;
+
+ return *this;
+}
+
+bool
+FragmentOrURL::operator==(const FragmentOrURL& aOther) const
+{
+ if (aOther.mIsLocalRef != mIsLocalRef) {
+ return false;
+ }
+
+ return EqualURIs(aOther.mURL, mURL);
+}
+
+bool
+FragmentOrURL::EqualsExceptRef(nsIURI* aURI) const
+{
+ bool ret = false;
+ mURL->EqualsExceptRef(aURI, &ret);
+ return ret;
+}
+
+void
+FragmentOrURL::GetSourceString(nsString &aRef) const
+{
+ MOZ_ASSERT(mURL);
+
+ nsCString cref;
+ if (mIsLocalRef) {
+ mURL->GetRef(cref);
+ cref.Insert('#', 0);
+ } else {
+ mURL->GetSpec(cref);
+ }
+
+ aRef = NS_ConvertUTF8toUTF16(cref);
+}
+
+already_AddRefed<nsIURI>
+FragmentOrURL::Resolve(nsIURI* aURI) const
+{
+ nsCOMPtr<nsIURI> result;
+
+ if (mIsLocalRef) {
+ nsCString ref;
+ mURL->GetRef(ref);
+
+ aURI->Clone(getter_AddRefs(result));
+ result->SetRef(ref);
+ } else {
+ result = mURL;
+ }
+
+ return result.forget();
+}
+
+already_AddRefed<nsIURI>
+FragmentOrURL::Resolve(nsIContent* aContent) const
+{
+ nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
+ return Resolve(url);
+}
+
+// --------------------
// nsStyleClipPath
//
nsStyleClipPath::nsStyleClipPath()
: mURL(nullptr)
, mType(StyleClipPathType::None_)
, mSizingBox(StyleClipShapeSizing::NoBox)
{
}
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3204,16 +3204,49 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
}
protected:
nscoord mColumnRuleWidth; // [reset] coord
nscoord mTwipsPerPixel;
};
+struct FragmentOrURL
+{
+ FragmentOrURL() : mIsLocalRef(false) {}
+ FragmentOrURL(const FragmentOrURL& aSource)
+ : mIsLocalRef(false)
+ { *this = aSource; }
+
+ void SetValue(const nsCSSValue* aValue);
+ void SetNull();
+
+ FragmentOrURL& operator=(const FragmentOrURL& aOther);
+ bool operator==(const FragmentOrURL& aOther) const;
+ bool operator!=(const FragmentOrURL& aOther) const {
+ return !(*this == aOther);
+ }
+
+ bool EqualsExceptRef(nsIURI* aURI) const;
+
+ nsIURI* GetSourceURL() const { return mURL; }
+ void GetSourceString(nsString& aRef) const;
+
+ // When matching a url with mIsLocalRef set, resolve it against aURI;
+ // Otherwise, ignore aURL and return mURL directly.
+ already_AddRefed<nsIURI> Resolve(nsIURI* aURI) const;
+ already_AddRefed<nsIURI> Resolve(nsIContent* aContent) const;
+
+ bool IsLocalRef() const { return mIsLocalRef; }
+
+private:
+ nsCOMPtr<nsIURI> mURL;
+ bool mIsLocalRef;
+};
+
enum nsStyleSVGPaintType {
eStyleSVGPaintType_None = 1,
eStyleSVGPaintType_Color,
eStyleSVGPaintType_Server,
eStyleSVGPaintType_ContextFill,
eStyleSVGPaintType_ContextStroke
};