diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 114028e8ab4..42a8f3aeac3 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -96,6 +96,13 @@ nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue) mValue.mGradient->AddRef(); } +nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue) + : mUnit(eCSSUnit_TokenStream) +{ + mValue.mTokenStream = aValue; + mValue.mTokenStream->AddRef(); +} + nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) : mUnit(aCopy.mUnit) { @@ -132,6 +139,10 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) mValue.mGradient = aCopy.mValue.mGradient; mValue.mGradient->AddRef(); } + else if (eCSSUnit_TokenStream == mUnit) { + mValue.mTokenStream = aCopy.mValue.mTokenStream; + mValue.mTokenStream->AddRef(); + } else if (eCSSUnit_Pair == mUnit) { mValue.mPair = aCopy.mValue.mPair; mValue.mPair->AddRef(); @@ -206,6 +217,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const else if (eCSSUnit_Gradient == mUnit) { return *mValue.mGradient == *aOther.mValue.mGradient; } + else if (eCSSUnit_TokenStream == mUnit) { + return *mValue.mTokenStream == *aOther.mValue.mTokenStream; + } else if (eCSSUnit_Pair == mUnit) { return *mValue.mPair == *aOther.mValue.mPair; } @@ -291,6 +305,8 @@ void nsCSSValue::DoReset() mValue.mImage->Release(); } else if (eCSSUnit_Gradient == mUnit) { mValue.mGradient->Release(); + } else if (eCSSUnit_TokenStream == mUnit) { + mValue.mTokenStream->Release(); } else if (eCSSUnit_Pair == mUnit) { mValue.mPair->Release(); } else if (eCSSUnit_Triplet == mUnit) { @@ -388,6 +404,14 @@ void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue) mValue.mGradient->AddRef(); } +void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue) +{ + Reset(); + mUnit = eCSSUnit_TokenStream; + mValue.mTokenStream = aValue; + mValue.mTokenStream->AddRef(); +} + void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue) { // pairs should not be used for null/inherit/initial values @@ -1137,6 +1161,15 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const } aResult.AppendLiteral(")"); + } else if (eCSSUnit_TokenStream == unit) { + nsCSSProperty shorthand = mValue.mTokenStream->mShorthandPropertyID; + if (shorthand == eCSSProperty_UNKNOWN || + nsCSSProps::PropHasFlags(shorthand, CSS_PROPERTY_IS_ALIAS)) { + // We treat serialization of aliases like '-moz-transform' as a special + // case, since it really wants to be serialized as if it were a longhand + // even though it is implemented as a shorthand. + aResult.Append(mValue.mTokenStream->mTokenStream); + } } else if (eCSSUnit_Pair == unit) { if (eCSSProperty_font_variant_alternates == aProperty) { int32_t intValue = GetPairValue().mXValue.GetIntValue(); @@ -1219,6 +1252,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const case eCSSUnit_Percent: aResult.Append(PRUnichar('%')); break; case eCSSUnit_Number: break; case eCSSUnit_Gradient: break; + case eCSSUnit_TokenStream: break; case eCSSUnit_Pair: break; case eCSSUnit_Triplet: break; case eCSSUnit_Rect: break; @@ -1321,6 +1355,11 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf); break; + // TokenStream + case eCSSUnit_TokenStream: + n += mValue.mTokenStream->SizeOfIncludingThis(aMallocSizeOf); + break; + // Pair case eCSSUnit_Pair: n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf); @@ -1929,6 +1968,28 @@ nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) con return n; } +// --- nsCSSValueTokenStream ------------ + +nsCSSValueTokenStream::nsCSSValueTokenStream() + : mPropertyID(eCSSProperty_UNKNOWN) + , mShorthandPropertyID(eCSSProperty_UNKNOWN) +{ + MOZ_COUNT_CTOR(nsCSSValueTokenStream); +} + +nsCSSValueTokenStream::~nsCSSValueTokenStream() +{ + MOZ_COUNT_DTOR(nsCSSValueTokenStream); +} + +size_t +nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t n = aMallocSizeOf(this); + n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + return n; +} + // --- nsCSSCornerSizes ----------------- nsCSSCornerSizes::nsCSSCornerSizes(void) diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 36d3c51ef35..260de26102c 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -12,6 +12,8 @@ #include "mozilla/FloatingPoint.h" #include "mozilla/MemoryReporting.h" +#include "nsIPrincipal.h" +#include "nsIURI.h" #include "nsCOMPtr.h" #include "nsCRTGlue.h" #include "nsCSSKeywords.h" @@ -187,6 +189,7 @@ enum nsCSSUnit { eCSSUnit_URL = 40, // (nsCSSValue::URL*) value eCSSUnit_Image = 41, // (nsCSSValue::Image*) value eCSSUnit_Gradient = 42, // (nsCSSValueGradient*) value + eCSSUnit_TokenStream = 43, // (nsCSSValueTokenStream*) value eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values @@ -249,6 +252,7 @@ enum nsCSSUnit { struct nsCSSValueGradient; struct nsCSSValuePair; struct nsCSSValuePair_heap; +struct nsCSSValueTokenStream; struct nsCSSRect; struct nsCSSRect_heap; struct nsCSSValueList; @@ -281,6 +285,7 @@ public: explicit nsCSSValue(mozilla::css::URLValue* aValue); explicit nsCSSValue(mozilla::css::ImageValue* aValue); explicit nsCSSValue(nsCSSValueGradient* aValue); + explicit nsCSSValue(nsCSSValueTokenStream* aValue); nsCSSValue(const nsCSSValue& aCopy); ~nsCSSValue() { Reset(); } @@ -419,6 +424,12 @@ public: return mValue.mGradient; } + nsCSSValueTokenStream* GetTokenStreamValue() const + { + NS_ABORT_IF_FALSE(mUnit == eCSSUnit_TokenStream, "not a token stream value"); + return mValue.mTokenStream; + } + // bodies of these are below inline nsCSSValuePair& GetPairValue(); inline const nsCSSValuePair& GetPairValue() const; @@ -484,6 +495,7 @@ public: void SetURLValue(mozilla::css::URLValue* aURI); void SetImageValue(mozilla::css::ImageValue* aImage); void SetGradientValue(nsCSSValueGradient* aGradient); + void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream); void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetDependentListValue(nsCSSValueList* aList); @@ -539,6 +551,7 @@ protected: mozilla::css::URLValue* mURL; mozilla::css::ImageValue* mImage; nsCSSValueGradient* mGradient; + nsCSSValueTokenStream* mTokenStream; nsCSSValuePair_heap* mPair; nsCSSRect_heap* mRect; nsCSSValueTriplet_heap* mTriplet; @@ -1130,6 +1143,66 @@ private: nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) MOZ_DELETE; }; +struct nsCSSValueTokenStream { + nsCSSValueTokenStream(); + ~nsCSSValueTokenStream(); + + bool operator==(const nsCSSValueTokenStream& aOther) const + { + bool eq; + return mPropertyID == aOther.mPropertyID && + mShorthandPropertyID == aOther.mShorthandPropertyID && + mTokenStream.Equals(aOther.mTokenStream) && + (mBaseURI == aOther.mBaseURI || + (mBaseURI && aOther.mBaseURI && + NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) && + eq)) && + (mSheetURI == aOther.mSheetURI || + (mSheetURI && aOther.mSheetURI && + NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) && + eq)) && + (mSheetPrincipal == aOther.mSheetPrincipal || + (mSheetPrincipal && aOther.mSheetPrincipal && + NS_SUCCEEDED(mSheetPrincipal->Equals(aOther.mSheetPrincipal, + &eq)) && + eq)); + } + + bool operator!=(const nsCSSValueTokenStream& aOther) const + { + return !(*this == aOther); + } + + NS_INLINE_DECL_REFCOUNTING(nsCSSValueTokenStream) + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + // The property that has mTokenStream as its unparsed specified value. + // When a variable reference is used in a shorthand property, a + // TokenStream value is stored as the specified value for each of its + // component longhand properties. + nsCSSProperty mPropertyID; + + // The shorthand property that had a value with a variable reference, + // which caused the longhand property identified by mPropertyID to have + // a TokenStream value. + nsCSSProperty mShorthandPropertyID; + + // The unparsed CSS corresponding to the specified value of the property. + // When the value of a shorthand property has a variable reference, the + // same mTokenStream value is used on each of the nsCSSValueTokenStream + // objects that will be set by parsing the shorthand. + nsString mTokenStream; + + nsCOMPtr mBaseURI; + nsCOMPtr mSheetURI; + nsCOMPtr mSheetPrincipal; + +private: + nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) MOZ_DELETE; + nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE; +}; + struct nsCSSCornerSizes { nsCSSCornerSizes(void); nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);