Bug 867089 - Validate the playbackRate before using it. r=ehsan
[gecko.git] / layout / style / nsCSSValue.h
blob267b6f479bb90473b7f7fae740926d55d4c3db0b
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"
13 #include "nsCOMPtr.h"
14 #include "nsCRTGlue.h"
15 #include "nsCSSKeywords.h"
16 #include "nsCSSProperty.h"
17 #include "nsColor.h"
18 #include "nsCoord.h"
19 #include "nsRefPtrHashtable.h"
20 #include "nsString.h"
21 #include "nsStringBuffer.h"
22 #include "nsTArray.h"
23 #include "nsStyleConsts.h"
24 #include "mozilla/FloatingPoint.h"
26 class imgRequestProxy;
27 class nsIDocument;
28 class nsIPrincipal;
29 class nsPresContext;
30 class nsIURI;
31 template <class T>
32 class nsPtrHashKey;
34 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
35 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
36 { \
37 type_ *cur = (ptr_)->member_; \
38 (ptr_)->member_ = nullptr; \
39 while (cur) { \
40 type_ *dlm_next = cur->member_; \
41 cur->member_ = nullptr; \
42 delete cur; \
43 cur = dlm_next; \
44 } \
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
49 // we return null.
50 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
51 { \
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_; \
56 if (!clm_clone) { \
57 delete (to_); \
58 return nullptr; \
59 } \
60 dest->member_ = clm_clone; \
61 dest = clm_clone; \
62 } \
65 namespace mozilla {
66 namespace css {
68 struct URLValue {
69 // Methods are not inline because using an nsIPrincipal means requiring
70 // caps, which leads to REQUIRES hell, since this header is included all
71 // over.
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);
83 ~URLValue();
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;
97 private:
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;
102 public:
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)
110 private:
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);
124 ~ImageValue();
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)
138 enum nsCSSUnit {
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
171 // calc values.
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
176 // computed values).
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
233 // Angular units
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
239 // Frequency units
240 eCSSUnit_Hertz = 2000, // (float) 1/seconds
241 eCSSUnit_Kilohertz = 2001, // (float) 1000 Hertz
243 // Time units
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;
251 struct nsCSSRect;
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;
260 class nsCSSValue {
261 public:
262 struct Array;
263 friend struct Array;
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)
271 : mUnit(aUnit)
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
296 * it to |aResult|.
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
306 * output device.
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,
345 "not an int value");
346 return mValue.mInt;
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");
375 aBuffer.Truncate();
376 uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
377 mValue.mString->ToString(len, aBuffer);
378 return 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,
404 "not a URL value");
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");
436 return mValue.mURL;
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,
448 "not a URL value");
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
456 // all over.
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)
465 DoReset();
467 private:
468 void DoReset();
470 public:
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);
486 void SetAutoValue();
487 void SetInheritValue();
488 void SetInitialValue();
489 void SetNoneValue();
490 void SetAllValue();
491 void SetNormalValue();
492 void SetSystemFontValue();
493 void SetDummyValue();
494 void SetDummyInheritValue();
496 // These are a little different - they allocate storage for you and
497 // return a handle.
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
510 // failure.
511 static already_AddRefed<nsStringBuffer>
512 BufferFromString(const nsString& aValue);
514 size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
516 private:
517 static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) {
518 return static_cast<PRUnichar*>(aBuffer->Data());
521 protected:
522 nsCSSUnit mUnit;
523 union {
524 int32_t mInt;
525 float mFloat;
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;
529 nscolor mColor;
530 Array* mArray;
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;
541 } mValue;
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)
569 return false;
570 for (size_t i = 0; i < mCount; ++i)
571 if ((*this)[i] != aOther[i])
572 return false;
573 return true;
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?
578 void AddRef() {
579 if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
580 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
581 return;
583 ++mRefCnt;
584 NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
586 void Release() {
587 if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
588 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
589 return;
591 --mRefCnt;
592 NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
593 if (mRefCnt == 0)
594 delete this;
597 private:
599 size_t mRefCnt;
600 const size_t mCount;
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
603 // alignment.
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)
622 : mRefCnt(0)
623 , mCount(aItemCount)
625 MOZ_COUNT_CTOR(nsCSSValue::Array);
626 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
627 new (val) nsCSSValue();
631 ~Array()
633 MOZ_COUNT_DTOR(nsCSSValue::Array);
634 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
635 val->~nsCSSValue();
639 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
641 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
643 private:
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); }
651 ~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;
663 nsCSSValue mValue;
664 nsCSSValueList* mNext;
666 private:
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)
689 return mValue.mList;
690 else {
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)
700 return mValue.mList;
701 else {
702 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
703 return mValue.mListDependent;
707 struct nsCSSRect {
708 nsCSSRect(void);
709 nsCSSRect(const nsCSSRect& aCopy);
710 ~nsCSSRect();
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 &&
732 mRight == aValue &&
733 mBottom == aValue &&
734 mLeft == aValue;
737 void Reset() {
738 mTop.Reset();
739 mRight.Reset();
740 mBottom.Reset();
741 mLeft.Reset();
744 bool HasValue() const {
745 return
746 mTop.GetUnit() != eCSSUnit_Null ||
747 mRight.GetUnit() != eCSSUnit_Null ||
748 mBottom.GetUnit() != eCSSUnit_Null ||
749 mLeft.GetUnit() != eCSSUnit_Null;
752 nsCSSValue mTop;
753 nsCSSValue mRight;
754 nsCSSValue mBottom;
755 nsCSSValue mLeft;
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.
772 inline nsCSSRect&
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 {
787 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);
806 ~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 &&
823 mYValue == aValue;
826 void SetBothValuesTo(const nsCSSValue& aValue) {
827 mXValue = aValue;
828 mYValue = aValue;
831 void Reset() {
832 mXValue.Reset();
833 mYValue.Reset();
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;
845 nsCSSValue mXValue;
846 nsCSSValue mYValue;
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 {
864 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);
885 ~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 &&
904 mYValue == aValue &&
905 mZValue == aValue;
908 void SetAllValuesTo(const nsCSSValue& aValue) {
909 mXValue = aValue;
910 mYValue = aValue;
911 mZValue = aValue;
914 void Reset() {
915 mXValue.Reset();
916 mYValue.Reset();
917 mZValue.Reset();
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;
928 nsCSSValue mXValue;
929 nsCSSValue mYValue;
930 nsCSSValue mZValue;
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;
991 nsCSSValue mXValue;
992 nsCSSValue mYValue;
993 nsCSSValuePairList* mNext;
995 private:
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;
1019 else {
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;
1030 else {
1031 NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1032 return mValue.mPairListDependent;
1036 struct nsCSSValueGradientStop {
1037 public:
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;
1045 nsCSSValue mColor;
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
1065 bool mIsRadial;
1066 bool mIsRepeating;
1067 bool mIsLegacySyntax;
1068 bool mIsExplicitSize;
1069 // line position and angle
1070 nsCSSValuePair mBgPos;
1071 nsCSSValue mAngle;
1073 // Only meaningful if mIsRadial is true
1074 private:
1075 nsCSSValue mRadialValues[2];
1076 public:
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])
1098 return false;
1100 if (mStops.Length() != aOther.mStops.Length())
1101 return false;
1103 for (uint32_t i = 0; i < mStops.Length(); i++) {
1104 if (mStops[i] != aOther.mStops[i])
1105 return false;
1108 return true;
1111 bool operator!=(const nsCSSValueGradient& aOther) const
1113 return !(*this == aOther);
1116 NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
1118 size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
1120 private:
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))
1141 return false;
1143 return true;
1146 bool operator!=(const nsCSSCornerSizes& aOther) const {
1147 NS_FOR_CSS_FULL_CORNERS(corner) {
1148 if (this->GetCorner(corner) != aOther.GetCorner(corner))
1149 return true;
1151 return false;
1154 bool HasValue() const {
1155 NS_FOR_CSS_FULL_CORNERS(corner) {
1156 if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null)
1157 return true;
1159 return false;
1162 void Reset();
1164 nsCSSValue mTopLeft;
1165 nsCSSValue mTopRight;
1166 nsCSSValue mBottomRight;
1167 nsCSSValue mBottomLeft;
1169 protected:
1170 typedef nsCSSValue nsCSSCornerSizes::*corner_type;
1171 static const corner_type corners[4];
1174 #endif /* nsCSSValue_h___ */