1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* representation of simple property values within CSS declarations */
8 #ifndef nsCSSValue_h___
9 #define nsCSSValue_h___
11 #include "mozilla/Attributes.h"
14 #include "nsCRTGlue.h"
15 #include "nsCSSKeywords.h"
16 #include "nsCSSProperty.h"
19 #include "nsRefPtrHashtable.h"
21 #include "nsStringBuffer.h"
23 #include "nsStyleConsts.h"
24 #include "mozilla/FloatingPoint.h"
26 class imgRequestProxy
;
34 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
35 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
37 type_ *cur = (ptr_)->member_; \
38 (ptr_)->member_ = nullptr; \
40 type_ *dlm_next = cur->member_; \
41 cur->member_ = nullptr; \
47 // Clones a linked list iteratively to avoid blowing up the stack.
48 // If it fails to clone the entire list then 'to_' is deleted and
50 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
52 type_ *dest = (to_); \
53 (to_)->member_ = nullptr; \
54 for (const type_ *src = (from_)->member_; src; src = src->member_) { \
55 type_ *clm_clone = src->Clone args_; \
60 dest->member_ = clm_clone; \
69 // Methods are not inline because using an nsIPrincipal means requiring
70 // caps, which leads to REQUIRES hell, since this header is included all
73 // For both constructors aString must not be null.
74 // For both constructors aOriginPrincipal must not be null.
75 // Construct with a base URI; this will create the actual URI lazily from
76 // aString and aBaseURI.
77 URLValue(nsStringBuffer
* aString
, nsIURI
* aBaseURI
, nsIURI
* aReferrer
,
78 nsIPrincipal
* aOriginPrincipal
);
79 // Construct with the actual URI.
80 URLValue(nsIURI
* aURI
, nsStringBuffer
* aString
, nsIURI
* aReferrer
,
81 nsIPrincipal
* aOriginPrincipal
);
85 bool operator==(const URLValue
& aOther
) const;
87 // URIEquals only compares URIs and principals (unlike operator==, which
88 // also compares the original strings). URIEquals also assumes that the
89 // mURI member of both URL objects is non-null. Do NOT call this method
90 // unless you're sure this is the case.
91 bool URIEquals(const URLValue
& aOther
) const;
93 nsIURI
* GetURI() const;
95 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
98 // If mURIResolved is false, mURI stores the base URI.
99 // If mURIResolved is true, mURI stores the URI we resolve to; this may be
100 // null if the URI is invalid.
101 mutable nsCOMPtr
<nsIURI
> mURI
;
103 nsStringBuffer
* mString
; // Could use nsRefPtr, but it'd add useless
104 // null-checks; this is never null.
105 nsCOMPtr
<nsIURI
> mReferrer
;
106 nsCOMPtr
<nsIPrincipal
> mOriginPrincipal
;
108 NS_INLINE_DECL_REFCOUNTING(URLValue
)
111 mutable bool mURIResolved
;
113 URLValue(const URLValue
& aOther
) MOZ_DELETE
;
114 URLValue
& operator=(const URLValue
& aOther
) MOZ_DELETE
;
117 struct ImageValue
: public URLValue
{
118 // Not making the constructor and destructor inline because that would
119 // force us to include imgIRequest.h, which leads to REQUIRES hell, since
120 // this header is included all over.
121 // aString must not be null.
122 ImageValue(nsIURI
* aURI
, nsStringBuffer
* aString
, nsIURI
* aReferrer
,
123 nsIPrincipal
* aOriginPrincipal
, nsIDocument
* aDocument
);
126 // Inherit operator== from URLValue
128 nsRefPtrHashtable
<nsPtrHashKey
<nsISupports
>, imgRequestProxy
> mRequests
;
130 // Override AddRef and Release to not only log ourselves correctly, but
131 // also so that we delete correctly without a virtual destructor
132 NS_INLINE_DECL_REFCOUNTING(ImageValue
)
139 eCSSUnit_Null
= 0, // (n/a) null unit, value is not specified
140 eCSSUnit_Auto
= 1, // (n/a) value is algorithmic
141 eCSSUnit_Inherit
= 2, // (n/a) value is inherited
142 eCSSUnit_Initial
= 3, // (n/a) value is default UA value
143 eCSSUnit_None
= 4, // (n/a) value is none
144 eCSSUnit_Normal
= 5, // (n/a) value is normal (algorithmic, different than auto)
145 eCSSUnit_System_Font
= 6, // (n/a) value is -moz-use-system-font
146 eCSSUnit_All
= 7, // (n/a) value is all
147 eCSSUnit_Dummy
= 8, // (n/a) a fake but specified value, used
148 // only in temporary values
149 eCSSUnit_DummyInherit
= 9, // (n/a) a fake but specified value, used
150 // only in temporary values
152 eCSSUnit_String
= 11, // (PRUnichar*) a string value
153 eCSSUnit_Ident
= 12, // (PRUnichar*) a string value
154 eCSSUnit_Families
= 13, // (PRUnichar*) a string value
155 eCSSUnit_Attr
= 14, // (PRUnichar*) a attr(string) value
156 eCSSUnit_Local_Font
= 15, // (PRUnichar*) a local font name
157 eCSSUnit_Font_Format
= 16, // (PRUnichar*) a font format name
158 eCSSUnit_Element
= 17, // (PRUnichar*) an element id
160 eCSSUnit_Array
= 20, // (nsCSSValue::Array*) a list of values
161 eCSSUnit_Counter
= 21, // (nsCSSValue::Array*) a counter(string,[string]) value
162 eCSSUnit_Counters
= 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
163 eCSSUnit_Cubic_Bezier
= 23, // (nsCSSValue::Array*) a list of float values
164 eCSSUnit_Steps
= 24, // (nsCSSValue::Array*) a list of (integer, enumerated)
165 eCSSUnit_Function
= 25, // (nsCSSValue::Array*) a function with
166 // parameters. First elem of array is name,
167 // the rest of the values are arguments.
169 // The top level of a calc() expression is eCSSUnit_Calc. All
170 // remaining eCSSUnit_Calc_* units only occur inside these toplevel
173 // eCSSUnit_Calc has an array with exactly 1 element. eCSSUnit_Calc
174 // exists so we can distinguish calc(2em) from 2em as specified values
175 // (but we drop this distinction for nsStyleCoord when we store
177 eCSSUnit_Calc
= 30, // (nsCSSValue::Array*) calc() value
178 // Plus, Minus, Times_* and Divided have arrays with exactly 2
179 // elements. a + b + c + d is grouped as ((a + b) + c) + d
180 eCSSUnit_Calc_Plus
= 31, // (nsCSSValue::Array*) + node within calc()
181 eCSSUnit_Calc_Minus
= 32, // (nsCSSValue::Array*) - within calc
182 eCSSUnit_Calc_Times_L
= 33, // (nsCSSValue::Array*) num * val within calc
183 eCSSUnit_Calc_Times_R
= 34, // (nsCSSValue::Array*) val * num within calc
184 eCSSUnit_Calc_Divided
= 35, // (nsCSSValue::Array*) / within calc
186 eCSSUnit_URL
= 40, // (nsCSSValue::URL*) value
187 eCSSUnit_Image
= 41, // (nsCSSValue::Image*) value
188 eCSSUnit_Gradient
= 42, // (nsCSSValueGradient*) value
190 eCSSUnit_Pair
= 50, // (nsCSSValuePair*) pair of values
191 eCSSUnit_Triplet
= 51, // (nsCSSValueTriplet*) triplet of values
192 eCSSUnit_Rect
= 52, // (nsCSSRect*) rectangle (four values)
193 eCSSUnit_List
= 53, // (nsCSSValueList*) list of values
194 eCSSUnit_ListDep
= 54, // (nsCSSValueList*) same as List
195 // but does not own the list
196 eCSSUnit_PairList
= 55, // (nsCSSValuePairList*) list of value pairs
197 eCSSUnit_PairListDep
= 56, // (nsCSSValuePairList*) same as PairList
198 // but does not own the list
200 eCSSUnit_Integer
= 70, // (int) simple value
201 eCSSUnit_Enumerated
= 71, // (int) value has enumerated meaning
203 eCSSUnit_EnumColor
= 80, // (int) enumerated color (kColorKTable)
204 eCSSUnit_Color
= 81, // (nscolor) an RGBA value
206 eCSSUnit_Percent
= 90, // (float) 1.0 == 100%) value is percentage of something
207 eCSSUnit_Number
= 91, // (float) value is numeric (usually multiplier, different behavior that percent)
209 // Physical length units
210 eCSSUnit_PhysicalMillimeter
= 200, // (float) 1/25.4 inch
212 // Length units - relative
213 // Viewport relative measure
214 eCSSUnit_ViewportWidth
= 700, // (float) 1% of the width of the initial containing block
215 eCSSUnit_ViewportHeight
= 701, // (float) 1% of the height of the initial containing block
216 eCSSUnit_ViewportMin
= 702, // (float) smaller of ViewportWidth and ViewportHeight
217 eCSSUnit_ViewportMax
= 703, // (float) larger of ViewportWidth and ViewportHeight
219 // Font relative measure
220 eCSSUnit_EM
= 800, // (float) == current font size
221 eCSSUnit_XHeight
= 801, // (float) distance from top of lower case x to baseline
222 eCSSUnit_Char
= 802, // (float) number of characters, used for width with monospace font
223 eCSSUnit_RootEM
= 803, // (float) == root element font size
225 // Screen relative measure
226 eCSSUnit_Point
= 900, // (float) 4/3 of a CSS pixel
227 eCSSUnit_Inch
= 901, // (float) 96 CSS pixels
228 eCSSUnit_Millimeter
= 902, // (float) 96/25.4 CSS pixels
229 eCSSUnit_Centimeter
= 903, // (float) 96/2.54 CSS pixels
230 eCSSUnit_Pica
= 904, // (float) 12 points == 16 CSS pixls
231 eCSSUnit_Pixel
= 905, // (float) CSS pixel unit
234 eCSSUnit_Degree
= 1000, // (float) 360 per circle
235 eCSSUnit_Grad
= 1001, // (float) 400 per circle
236 eCSSUnit_Radian
= 1002, // (float) 2*pi per circle
237 eCSSUnit_Turn
= 1003, // (float) 1 per circle
240 eCSSUnit_Hertz
= 2000, // (float) 1/seconds
241 eCSSUnit_Kilohertz
= 2001, // (float) 1000 Hertz
244 eCSSUnit_Seconds
= 3000, // (float) Standard time
245 eCSSUnit_Milliseconds
= 3001 // (float) 1/1000 second
248 struct nsCSSValueGradient
;
249 struct nsCSSValuePair
;
250 struct nsCSSValuePair_heap
;
252 struct nsCSSRect_heap
;
253 struct nsCSSValueList
;
254 struct nsCSSValueList_heap
;
255 struct nsCSSValuePairList
;
256 struct nsCSSValuePairList_heap
;
257 struct nsCSSValueTriplet
;
258 struct nsCSSValueTriplet_heap
;
265 friend struct mozilla::css::URLValue
;
267 friend struct mozilla::css::ImageValue
;
269 // for valueless units only (null, auto, inherit, none, all, normal)
270 explicit nsCSSValue(nsCSSUnit aUnit
= eCSSUnit_Null
)
273 NS_ABORT_IF_FALSE(aUnit
<= eCSSUnit_DummyInherit
, "not a valueless unit");
276 nsCSSValue(int32_t aValue
, nsCSSUnit aUnit
);
277 nsCSSValue(float aValue
, nsCSSUnit aUnit
);
278 nsCSSValue(const nsString
& aValue
, nsCSSUnit aUnit
);
279 nsCSSValue(Array
* aArray
, nsCSSUnit aUnit
);
280 explicit nsCSSValue(mozilla::css::URLValue
* aValue
);
281 explicit nsCSSValue(mozilla::css::ImageValue
* aValue
);
282 explicit nsCSSValue(nsCSSValueGradient
* aValue
);
283 nsCSSValue(const nsCSSValue
& aCopy
);
284 ~nsCSSValue() { Reset(); }
286 nsCSSValue
& operator=(const nsCSSValue
& aCopy
);
287 bool operator==(const nsCSSValue
& aOther
) const;
289 bool operator!=(const nsCSSValue
& aOther
) const
291 return !(*this == aOther
);
295 * Serialize |this| as a specified value for |aProperty| and append
298 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
300 nsCSSUnit
GetUnit() const { return mUnit
; }
301 bool IsLengthUnit() const
302 { return eCSSUnit_PhysicalMillimeter
<= mUnit
&& mUnit
<= eCSSUnit_Pixel
; }
304 * A "fixed" length unit is one that means a specific physical length
305 * which we try to match based on the physical characteristics of an
308 bool IsFixedLengthUnit() const
309 { return mUnit
== eCSSUnit_PhysicalMillimeter
; }
311 * What the spec calls relative length units is, for us, split
312 * between relative length units and pixel length units.
314 * A "relative" length unit is a multiple of some derived metric,
315 * such as a font em-size, which itself was controlled by an input CSS
316 * length. Relative length units should not be scaled by zooming, since
317 * the underlying CSS length would already have been scaled.
319 bool IsRelativeLengthUnit() const
320 { return eCSSUnit_EM
<= mUnit
&& mUnit
<= eCSSUnit_RootEM
; }
322 * A "pixel" length unit is a some multiple of CSS pixels.
324 bool IsPixelLengthUnit() const
325 { return eCSSUnit_Point
<= mUnit
&& mUnit
<= eCSSUnit_Pixel
; }
326 bool IsAngularUnit() const
327 { return eCSSUnit_Degree
<= mUnit
&& mUnit
<= eCSSUnit_Turn
; }
328 bool IsFrequencyUnit() const
329 { return eCSSUnit_Hertz
<= mUnit
&& mUnit
<= eCSSUnit_Kilohertz
; }
330 bool IsTimeUnit() const
331 { return eCSSUnit_Seconds
<= mUnit
&& mUnit
<= eCSSUnit_Milliseconds
; }
332 bool IsCalcUnit() const
333 { return eCSSUnit_Calc
<= mUnit
&& mUnit
<= eCSSUnit_Calc_Divided
; }
335 bool UnitHasStringValue() const
336 { return eCSSUnit_String
<= mUnit
&& mUnit
<= eCSSUnit_Element
; }
337 bool UnitHasArrayValue() const
338 { return eCSSUnit_Array
<= mUnit
&& mUnit
<= eCSSUnit_Calc_Divided
; }
340 int32_t GetIntValue() const
342 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Integer
||
343 mUnit
== eCSSUnit_Enumerated
||
344 mUnit
== eCSSUnit_EnumColor
,
349 float GetPercentValue() const
351 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Percent
, "not a percent value");
352 return mValue
.mFloat
;
355 float GetFloatValue() const
357 NS_ABORT_IF_FALSE(eCSSUnit_Number
<= mUnit
, "not a float value");
358 MOZ_ASSERT(!MOZ_DOUBLE_IS_NaN(mValue
.mFloat
));
359 return mValue
.mFloat
;
362 float GetAngleValue() const
364 NS_ABORT_IF_FALSE(eCSSUnit_Degree
<= mUnit
&&
365 mUnit
<= eCSSUnit_Turn
, "not an angle value");
366 return mValue
.mFloat
;
369 // Converts any angle to radians.
370 double GetAngleValueInRadians() const;
372 nsAString
& GetStringValue(nsAString
& aBuffer
) const
374 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
376 uint32_t len
= NS_strlen(GetBufferValue(mValue
.mString
));
377 mValue
.mString
->ToString(len
, aBuffer
);
381 const PRUnichar
* GetStringBufferValue() const
383 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
384 return GetBufferValue(mValue
.mString
);
387 nscolor
GetColorValue() const
389 NS_ABORT_IF_FALSE((mUnit
== eCSSUnit_Color
), "not a color value");
390 return mValue
.mColor
;
393 bool IsNonTransparentColor() const;
395 Array
* GetArrayValue() const
397 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "not an array value");
398 return mValue
.mArray
;
401 nsIURI
* GetURLValue() const
403 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_URL
|| mUnit
== eCSSUnit_Image
,
405 return mUnit
== eCSSUnit_URL
?
406 mValue
.mURL
->GetURI() : mValue
.mImage
->GetURI();
409 nsCSSValueGradient
* GetGradientValue() const
411 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Gradient
, "not a gradient value");
412 return mValue
.mGradient
;
415 // bodies of these are below
416 inline nsCSSValuePair
& GetPairValue();
417 inline const nsCSSValuePair
& GetPairValue() const;
419 inline nsCSSRect
& GetRectValue();
420 inline const nsCSSRect
& GetRectValue() const;
422 inline nsCSSValueList
* GetListValue();
423 inline const nsCSSValueList
* GetListValue() const;
425 inline nsCSSValuePairList
* GetPairListValue();
426 inline const nsCSSValuePairList
* GetPairListValue() const;
428 inline nsCSSValueTriplet
& GetTripletValue();
429 inline const nsCSSValueTriplet
& GetTripletValue() const;
431 mozilla::css::URLValue
* GetURLStructValue() const
433 // Not allowing this for Image values, because if the caller takes
434 // a ref to them they won't be able to delete them properly.
435 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_URL
, "not a URL value");
439 mozilla::css::ImageValue
* GetImageStructValue() const
441 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Image
, "not an Image value");
442 return mValue
.mImage
;
445 const PRUnichar
* GetOriginalURLValue() const
447 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_URL
|| mUnit
== eCSSUnit_Image
,
449 return GetBufferValue(mUnit
== eCSSUnit_URL
?
450 mValue
.mURL
->mString
:
451 mValue
.mImage
->mString
);
454 // Not making this inline because that would force us to include
455 // imgIRequest.h, which leads to REQUIRES hell, since this header is included
457 imgRequestProxy
* GetImageValue(nsIDocument
* aDocument
) const;
459 nscoord
GetFixedLength(nsPresContext
* aPresContext
) const;
460 nscoord
GetPixelLength() const;
462 void Reset() // sets to null
464 if (mUnit
!= eCSSUnit_Null
)
471 void SetIntValue(int32_t aValue
, nsCSSUnit aUnit
);
472 void SetPercentValue(float aValue
);
473 void SetFloatValue(float aValue
, nsCSSUnit aUnit
);
474 void SetStringValue(const nsString
& aValue
, nsCSSUnit aUnit
);
475 void SetColorValue(nscolor aValue
);
476 void SetArrayValue(nsCSSValue::Array
* aArray
, nsCSSUnit aUnit
);
477 void SetURLValue(mozilla::css::URLValue
* aURI
);
478 void SetImageValue(mozilla::css::ImageValue
* aImage
);
479 void SetGradientValue(nsCSSValueGradient
* aGradient
);
480 void SetPairValue(const nsCSSValuePair
* aPair
);
481 void SetPairValue(const nsCSSValue
& xValue
, const nsCSSValue
& yValue
);
482 void SetDependentListValue(nsCSSValueList
* aList
);
483 void SetDependentPairListValue(nsCSSValuePairList
* aList
);
484 void SetTripletValue(const nsCSSValueTriplet
* aTriplet
);
485 void SetTripletValue(const nsCSSValue
& xValue
, const nsCSSValue
& yValue
, const nsCSSValue
& zValue
);
487 void SetInheritValue();
488 void SetInitialValue();
491 void SetNormalValue();
492 void SetSystemFontValue();
493 void SetDummyValue();
494 void SetDummyInheritValue();
496 // These are a little different - they allocate storage for you and
498 nsCSSRect
& SetRectValue();
499 nsCSSValueList
* SetListValue();
500 nsCSSValuePairList
* SetPairListValue();
502 void StartImageLoad(nsIDocument
* aDocument
) const; // Only pretend const
504 // Initializes as a function value with the specified function id.
505 Array
* InitFunction(nsCSSKeyword aFunctionId
, uint32_t aNumArgs
);
506 // Checks if this is a function value with the specified function id.
507 bool EqualsFunction(nsCSSKeyword aFunctionId
) const;
509 // Returns an already addrefed buffer. Can return null on allocation
511 static already_AddRefed
<nsStringBuffer
>
512 BufferFromString(const nsString
& aValue
);
514 size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
517 static const PRUnichar
* GetBufferValue(nsStringBuffer
* aBuffer
) {
518 return static_cast<PRUnichar
*>(aBuffer
->Data());
526 // Note: the capacity of the buffer may exceed the length of the string.
527 // If we're of a string type, mString is not null.
528 nsStringBuffer
* mString
;
531 mozilla::css::URLValue
* mURL
;
532 mozilla::css::ImageValue
* mImage
;
533 nsCSSValueGradient
* mGradient
;
534 nsCSSValuePair_heap
* mPair
;
535 nsCSSRect_heap
* mRect
;
536 nsCSSValueTriplet_heap
* mTriplet
;
537 nsCSSValueList_heap
* mList
;
538 nsCSSValueList
* mListDependent
;
539 nsCSSValuePairList_heap
* mPairList
;
540 nsCSSValuePairList
* mPairListDependent
;
544 struct nsCSSValue::Array
{
546 // return |Array| with reference count of zero
547 static Array
* Create(size_t aItemCount
) {
548 return new (aItemCount
) Array(aItemCount
);
551 nsCSSValue
& operator[](size_t aIndex
) {
552 NS_ABORT_IF_FALSE(aIndex
< mCount
, "out of range");
553 return mArray
[aIndex
];
556 const nsCSSValue
& operator[](size_t aIndex
) const {
557 NS_ABORT_IF_FALSE(aIndex
< mCount
, "out of range");
558 return mArray
[aIndex
];
561 nsCSSValue
& Item(size_t aIndex
) { return (*this)[aIndex
]; }
562 const nsCSSValue
& Item(size_t aIndex
) const { return (*this)[aIndex
]; }
564 size_t Count() const { return mCount
; }
566 bool operator==(const Array
& aOther
) const
568 if (mCount
!= aOther
.mCount
)
570 for (size_t i
= 0; i
< mCount
; ++i
)
571 if ((*this)[i
] != aOther
[i
])
576 // XXXdholbert This uses a size_t ref count. Should we use a variant
577 // of NS_INLINE_DECL_REFCOUNTING that takes a type as an argument?
579 if (mRefCnt
== size_t(-1)) { // really want SIZE_MAX
580 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
584 NS_LOG_ADDREF(this, mRefCnt
, "nsCSSValue::Array", sizeof(*this));
587 if (mRefCnt
== size_t(-1)) { // really want SIZE_MAX
588 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
592 NS_LOG_RELEASE(this, mRefCnt
, "nsCSSValue::Array");
601 // This must be the last sub-object, since we extend this array to
602 // be of size mCount; it needs to be a sub-object so it gets proper
604 nsCSSValue mArray
[1];
606 void* operator new(size_t aSelfSize
, size_t aItemCount
) CPP_THROW_NEW
{
607 NS_ABORT_IF_FALSE(aItemCount
> 0, "cannot have a 0 item count");
608 return ::operator new(aSelfSize
+ sizeof(nsCSSValue
) * (aItemCount
- 1));
611 void operator delete(void* aPtr
) { ::operator delete(aPtr
); }
613 nsCSSValue
* First() { return mArray
; }
615 const nsCSSValue
* First() const { return mArray
; }
617 #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var) \
618 for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount; \
619 var != var##_end; ++var)
621 Array(size_t aItemCount
)
625 MOZ_COUNT_CTOR(nsCSSValue::Array
);
626 CSSVALUE_LIST_FOR_EXTRA_VALUES(val
) {
627 new (val
) nsCSSValue();
633 MOZ_COUNT_DTOR(nsCSSValue::Array
);
634 CSSVALUE_LIST_FOR_EXTRA_VALUES(val
) {
639 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
641 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
644 Array(const Array
& aOther
) MOZ_DELETE
;
645 Array
& operator=(const Array
& aOther
) MOZ_DELETE
;
648 // Prefer nsCSSValue::Array for lists of fixed size.
649 struct nsCSSValueList
{
650 nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList
); }
653 nsCSSValueList
* Clone() const; // makes a deep copy
654 void CloneInto(nsCSSValueList
* aList
) const; // makes a deep copy into aList
655 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
657 bool operator==(nsCSSValueList
const& aOther
) const;
658 bool operator!=(const nsCSSValueList
& aOther
) const
659 { return !(*this == aOther
); }
661 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
664 nsCSSValueList
* mNext
;
667 nsCSSValueList(const nsCSSValueList
& aCopy
) // makes a shallow copy
668 : mValue(aCopy
.mValue
), mNext(nullptr)
670 MOZ_COUNT_CTOR(nsCSSValueList
);
674 // nsCSSValueList_heap differs from nsCSSValueList only in being
675 // refcounted. It should not be necessary to use this class directly;
676 // it's an implementation detail of nsCSSValue.
677 struct nsCSSValueList_heap
: public nsCSSValueList
{
678 NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap
)
680 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
683 // This has to be here so that the relationship between nsCSSValueList
684 // and nsCSSValueList_heap is visible.
685 inline nsCSSValueList
*
686 nsCSSValue::GetListValue()
688 if (mUnit
== eCSSUnit_List
)
691 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_ListDep
, "not a pairlist value");
692 return mValue
.mListDependent
;
696 inline const nsCSSValueList
*
697 nsCSSValue::GetListValue() const
699 if (mUnit
== eCSSUnit_List
)
702 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_ListDep
, "not a pairlist value");
703 return mValue
.mListDependent
;
709 nsCSSRect(const nsCSSRect
& aCopy
);
712 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
714 bool operator==(const nsCSSRect
& aOther
) const {
715 return mTop
== aOther
.mTop
&&
716 mRight
== aOther
.mRight
&&
717 mBottom
== aOther
.mBottom
&&
718 mLeft
== aOther
.mLeft
;
721 bool operator!=(const nsCSSRect
& aOther
) const {
722 return mTop
!= aOther
.mTop
||
723 mRight
!= aOther
.mRight
||
724 mBottom
!= aOther
.mBottom
||
725 mLeft
!= aOther
.mLeft
;
728 void SetAllSidesTo(const nsCSSValue
& aValue
);
730 bool AllSidesEqualTo(const nsCSSValue
& aValue
) const {
731 return mTop
== aValue
&&
744 bool HasValue() const {
746 mTop
.GetUnit() != eCSSUnit_Null
||
747 mRight
.GetUnit() != eCSSUnit_Null
||
748 mBottom
.GetUnit() != eCSSUnit_Null
||
749 mLeft
.GetUnit() != eCSSUnit_Null
;
757 typedef nsCSSValue
nsCSSRect::*side_type
;
758 static const side_type sides
[4];
761 // nsCSSRect_heap differs from nsCSSRect only in being
762 // refcounted. It should not be necessary to use this class directly;
763 // it's an implementation detail of nsCSSValue.
764 struct nsCSSRect_heap
: public nsCSSRect
{
765 NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap
)
767 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
770 // This has to be here so that the relationship between nsCSSRect
771 // and nsCSSRect_heap is visible.
773 nsCSSValue::GetRectValue()
775 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Rect
, "not a rect value");
776 return *mValue
.mRect
;
779 inline const nsCSSRect
&
780 nsCSSValue::GetRectValue() const
782 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Rect
, "not a rect value");
783 return *mValue
.mRect
;
786 struct nsCSSValuePair
{
789 MOZ_COUNT_CTOR(nsCSSValuePair
);
791 nsCSSValuePair(nsCSSUnit aUnit
)
792 : mXValue(aUnit
), mYValue(aUnit
)
794 MOZ_COUNT_CTOR(nsCSSValuePair
);
796 nsCSSValuePair(const nsCSSValue
& aXValue
, const nsCSSValue
& aYValue
)
797 : mXValue(aXValue
), mYValue(aYValue
)
799 MOZ_COUNT_CTOR(nsCSSValuePair
);
801 nsCSSValuePair(const nsCSSValuePair
& aCopy
)
802 : mXValue(aCopy
.mXValue
), mYValue(aCopy
.mYValue
)
804 MOZ_COUNT_CTOR(nsCSSValuePair
);
808 MOZ_COUNT_DTOR(nsCSSValuePair
);
811 bool operator==(const nsCSSValuePair
& aOther
) const {
812 return mXValue
== aOther
.mXValue
&&
813 mYValue
== aOther
.mYValue
;
816 bool operator!=(const nsCSSValuePair
& aOther
) const {
817 return mXValue
!= aOther
.mXValue
||
818 mYValue
!= aOther
.mYValue
;
821 bool BothValuesEqualTo(const nsCSSValue
& aValue
) const {
822 return mXValue
== aValue
&&
826 void SetBothValuesTo(const nsCSSValue
& aValue
) {
836 bool HasValue() const {
837 return mXValue
.GetUnit() != eCSSUnit_Null
||
838 mYValue
.GetUnit() != eCSSUnit_Null
;
841 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
843 size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
849 // nsCSSValuePair_heap differs from nsCSSValuePair only in being
850 // refcounted. It should not be necessary to use this class directly;
851 // it's an implementation detail of nsCSSValue.
852 struct nsCSSValuePair_heap
: public nsCSSValuePair
{
853 // forward constructor
854 nsCSSValuePair_heap(const nsCSSValue
& aXValue
, const nsCSSValue
& aYValue
)
855 : nsCSSValuePair(aXValue
, aYValue
)
858 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap
)
860 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
863 struct nsCSSValueTriplet
{
866 MOZ_COUNT_CTOR(nsCSSValueTriplet
);
868 nsCSSValueTriplet(nsCSSUnit aUnit
)
869 : mXValue(aUnit
), mYValue(aUnit
), mZValue(aUnit
)
871 MOZ_COUNT_CTOR(nsCSSValueTriplet
);
873 nsCSSValueTriplet(const nsCSSValue
& aXValue
,
874 const nsCSSValue
& aYValue
,
875 const nsCSSValue
& aZValue
)
876 : mXValue(aXValue
), mYValue(aYValue
), mZValue(aZValue
)
878 MOZ_COUNT_CTOR(nsCSSValueTriplet
);
880 nsCSSValueTriplet(const nsCSSValueTriplet
& aCopy
)
881 : mXValue(aCopy
.mXValue
), mYValue(aCopy
.mYValue
), mZValue(aCopy
.mZValue
)
883 MOZ_COUNT_CTOR(nsCSSValueTriplet
);
887 MOZ_COUNT_DTOR(nsCSSValueTriplet
);
890 bool operator==(const nsCSSValueTriplet
& aOther
) const {
891 return mXValue
== aOther
.mXValue
&&
892 mYValue
== aOther
.mYValue
&&
893 mZValue
== aOther
.mZValue
;
896 bool operator!=(const nsCSSValueTriplet
& aOther
) const {
897 return mXValue
!= aOther
.mXValue
||
898 mYValue
!= aOther
.mYValue
||
899 mZValue
!= aOther
.mZValue
;
902 bool AllValuesEqualTo(const nsCSSValue
& aValue
) const {
903 return mXValue
== aValue
&&
908 void SetAllValuesTo(const nsCSSValue
& aValue
) {
920 bool HasValue() const {
921 return mXValue
.GetUnit() != eCSSUnit_Null
||
922 mYValue
.GetUnit() != eCSSUnit_Null
||
923 mZValue
.GetUnit() != eCSSUnit_Null
;
926 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
933 // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
934 // refcounted. It should not be necessary to use this class directly;
935 // it's an implementation detail of nsCSSValue.
936 struct nsCSSValueTriplet_heap
: public nsCSSValueTriplet
{
937 // forward constructor
938 nsCSSValueTriplet_heap(const nsCSSValue
& aXValue
, const nsCSSValue
& aYValue
, const nsCSSValue
& aZValue
)
939 : nsCSSValueTriplet(aXValue
, aYValue
, aZValue
)
942 NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap
)
944 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
947 // This has to be here so that the relationship between nsCSSValuePair
948 // and nsCSSValuePair_heap is visible.
949 inline nsCSSValuePair
&
950 nsCSSValue::GetPairValue()
952 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Pair
, "not a pair value");
953 return *mValue
.mPair
;
956 inline const nsCSSValuePair
&
957 nsCSSValue::GetPairValue() const
959 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Pair
, "not a pair value");
960 return *mValue
.mPair
;
963 inline nsCSSValueTriplet
&
964 nsCSSValue::GetTripletValue()
966 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Triplet
, "not a triplet value");
967 return *mValue
.mTriplet
;
970 inline const nsCSSValueTriplet
&
971 nsCSSValue::GetTripletValue() const
973 NS_ABORT_IF_FALSE(mUnit
== eCSSUnit_Triplet
, "not a triplet value");
974 return *mValue
.mTriplet
;
977 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
978 struct nsCSSValuePairList
{
979 nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList
); }
980 ~nsCSSValuePairList();
982 nsCSSValuePairList
* Clone() const; // makes a deep copy
983 void AppendToString(nsCSSProperty aProperty
, nsAString
& aResult
) const;
985 bool operator==(const nsCSSValuePairList
& aOther
) const;
986 bool operator!=(const nsCSSValuePairList
& aOther
) const
987 { return !(*this == aOther
); }
989 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
993 nsCSSValuePairList
* mNext
;
996 nsCSSValuePairList(const nsCSSValuePairList
& aCopy
) // makes a shallow copy
997 : mXValue(aCopy
.mXValue
), mYValue(aCopy
.mYValue
), mNext(nullptr)
999 MOZ_COUNT_CTOR(nsCSSValuePairList
);
1003 // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
1004 // refcounted. It should not be necessary to use this class directly;
1005 // it's an implementation detail of nsCSSValue.
1006 struct nsCSSValuePairList_heap
: public nsCSSValuePairList
{
1007 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap
)
1009 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
1012 // This has to be here so that the relationship between nsCSSValuePairList
1013 // and nsCSSValuePairList_heap is visible.
1014 inline nsCSSValuePairList
*
1015 nsCSSValue::GetPairListValue()
1017 if (mUnit
== eCSSUnit_PairList
)
1018 return mValue
.mPairList
;
1020 NS_ABORT_IF_FALSE (mUnit
== eCSSUnit_PairListDep
, "not a pairlist value");
1021 return mValue
.mPairListDependent
;
1025 inline const nsCSSValuePairList
*
1026 nsCSSValue::GetPairListValue() const
1028 if (mUnit
== eCSSUnit_PairList
)
1029 return mValue
.mPairList
;
1031 NS_ABORT_IF_FALSE (mUnit
== eCSSUnit_PairListDep
, "not a pairlist value");
1032 return mValue
.mPairListDependent
;
1036 struct nsCSSValueGradientStop
{
1038 nsCSSValueGradientStop();
1039 // needed to keep bloat logs happy when we use the TArray
1040 // in nsCSSValueGradient
1041 nsCSSValueGradientStop(const nsCSSValueGradientStop
& aOther
);
1042 ~nsCSSValueGradientStop();
1044 nsCSSValue mLocation
;
1047 bool operator==(const nsCSSValueGradientStop
& aOther
) const
1049 return (mLocation
== aOther
.mLocation
&&
1050 mColor
== aOther
.mColor
);
1053 bool operator!=(const nsCSSValueGradientStop
& aOther
) const
1055 return !(*this == aOther
);
1058 size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
1061 struct nsCSSValueGradient
{
1062 nsCSSValueGradient(bool aIsRadial
, bool aIsRepeating
);
1064 // true if gradient is radial, false if it is linear
1067 bool mIsLegacySyntax
;
1068 bool mIsExplicitSize
;
1069 // line position and angle
1070 nsCSSValuePair mBgPos
;
1073 // Only meaningful if mIsRadial is true
1075 nsCSSValue mRadialValues
[2];
1077 nsCSSValue
& GetRadialShape() { return mRadialValues
[0]; }
1078 const nsCSSValue
& GetRadialShape() const { return mRadialValues
[0]; }
1079 nsCSSValue
& GetRadialSize() { return mRadialValues
[1]; }
1080 const nsCSSValue
& GetRadialSize() const { return mRadialValues
[1]; }
1081 nsCSSValue
& GetRadiusX() { return mRadialValues
[0]; }
1082 const nsCSSValue
& GetRadiusX() const { return mRadialValues
[0]; }
1083 nsCSSValue
& GetRadiusY() { return mRadialValues
[1]; }
1084 const nsCSSValue
& GetRadiusY() const { return mRadialValues
[1]; }
1086 InfallibleTArray
<nsCSSValueGradientStop
> mStops
;
1088 bool operator==(const nsCSSValueGradient
& aOther
) const
1090 if (mIsRadial
!= aOther
.mIsRadial
||
1091 mIsRepeating
!= aOther
.mIsRepeating
||
1092 mIsLegacySyntax
!= aOther
.mIsLegacySyntax
||
1093 mIsExplicitSize
!= aOther
.mIsExplicitSize
||
1094 mBgPos
!= aOther
.mBgPos
||
1095 mAngle
!= aOther
.mAngle
||
1096 mRadialValues
[0] != aOther
.mRadialValues
[0] ||
1097 mRadialValues
[1] != aOther
.mRadialValues
[1])
1100 if (mStops
.Length() != aOther
.mStops
.Length())
1103 for (uint32_t i
= 0; i
< mStops
.Length(); i
++) {
1104 if (mStops
[i
] != aOther
.mStops
[i
])
1111 bool operator!=(const nsCSSValueGradient
& aOther
) const
1113 return !(*this == aOther
);
1116 NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient
)
1118 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf
) const;
1121 nsCSSValueGradient(const nsCSSValueGradient
& aOther
) MOZ_DELETE
;
1122 nsCSSValueGradient
& operator=(const nsCSSValueGradient
& aOther
) MOZ_DELETE
;
1125 struct nsCSSCornerSizes
{
1126 nsCSSCornerSizes(void);
1127 nsCSSCornerSizes(const nsCSSCornerSizes
& aCopy
);
1128 ~nsCSSCornerSizes();
1130 // argument is a "full corner" constant from nsStyleConsts.h
1131 nsCSSValue
const & GetCorner(uint32_t aCorner
) const {
1132 return this->*corners
[aCorner
];
1134 nsCSSValue
& GetCorner(uint32_t aCorner
) {
1135 return this->*corners
[aCorner
];
1138 bool operator==(const nsCSSCornerSizes
& aOther
) const {
1139 NS_FOR_CSS_FULL_CORNERS(corner
) {
1140 if (this->GetCorner(corner
) != aOther
.GetCorner(corner
))
1146 bool operator!=(const nsCSSCornerSizes
& aOther
) const {
1147 NS_FOR_CSS_FULL_CORNERS(corner
) {
1148 if (this->GetCorner(corner
) != aOther
.GetCorner(corner
))
1154 bool HasValue() const {
1155 NS_FOR_CSS_FULL_CORNERS(corner
) {
1156 if (this->GetCorner(corner
).GetUnit() != eCSSUnit_Null
)
1164 nsCSSValue mTopLeft
;
1165 nsCSSValue mTopRight
;
1166 nsCSSValue mBottomRight
;
1167 nsCSSValue mBottomLeft
;
1170 typedef nsCSSValue
nsCSSCornerSizes::*corner_type
;
1171 static const corner_type corners
[4];
1174 #endif /* nsCSSValue_h___ */